Q:

Moving points with scaling grid (points in list)

I am making some examples for my school work.
Now I am stuck at one point. I will try to include as litllet code as I can but I am not sure what you all need..
(sorry for including names and coments in my native lang)
Heres what I need to do:
I got my "painting program" where you can add points by clicking and then it draws lines to each other. I programed a grid and when you check a checkbox then it looks for closest possible point in rastr(grid)list and then applies its coordinates to the point you're trying to paint with mouse.
You can also scale that grid by trackbar values.
Now here comes my problem: I need to move my painted points with the grid when i'm scaling it. I have no clue since i cant just simply do for each point in grid.X = p.X + trackbarValue. (geting error)
Here is my code for grid and painting:
List<Point> rastr = new List<Point>(); //rastr means grid
List<Point> body = new List<Point>(); //painting poits

   private void panel1_Paint(object sender, PaintEventArgs e)
   {
            Graphics kp = e.Graphics;
            foreach (Point p in body)
            {
                kp.FillEllipse(st, p.X-s/2, p.Y-s/2, s, s); 
            }
            //double buffer nezapomenout
            if (body.Count>1)
            {
                kp.DrawLines(pero, body.ToArray());//to array prevedeni na pole
            }
            for (int x = 0; x < panel1.Width; x += trackBarGrid.Value)
                for (int y = 0; y < panel1.Height; y += trackBarGrid.Value)
                {
                    if (showGrid == true)
                    {
                        kp.FillEllipse(grid, x-2, y-2, 4, 4);
                    }
                    Point gridpoint = new Point(x,y);
                    rastr.Add(gridpoint);
                }
        }

Here is looking for the closest one in grid and then applying coordinates:
private void panel1_MouseClick(object sender, MouseEventArgs e)
    {
        if (useGrid == true)
        {
            //rozjedu cykly abych nasel nejblizsi bod (porovnavat jednotlivy koordinace)
            foreach (Point p in rastr)
            {
                if (e.Location.X - p.X < trackBarGrid.Value / 2) //kdyz odecteme pozici bodu v listu rastr.x od pozice x kliknuti nesmi byt vetsi nez polovina delky odsazeni rastrovych bodu
                    if (e.Location.Y - p.Y < trackBarGrid.Value / 2) // to same jen s pozici Y
                    {
                        Point zapsat = new Point(p.X, p.Y);
                        body.Add(zapsat); //od tyhle pozice najit nejblizsi point v gridu
                        break;//bod jsme uspesne nasli. Nyni musime cyklus uzavrit aby se nezacli pridavat body ktere nechceme
                    }
            }
            panel1.Refresh();
        }
        else {
            body.Add(e.Location);
            panel1.Refresh();
        }   
    }

Also my trackbar event:
    private void trackBarGrid_Scroll(object sender, EventArgs e)
    {
        rastr.Clear();
        panel1.Refresh();
    }

And my poor attempt on this
    private void trackBarGrid_Scroll(object sender, EventArgs e)
    {
        foreach (Point p in rastr)
        {
            p.X += TrackBarValue;
            p.Y += TrackBarValue;
        }
        panel1.Refresh();
    }

One last note that I don't need to keep that "freehand" painting. I can just use that grid one.
Here are some pictures..
Before scaling
After scaling

A:

There are two ways you can chose to scale your graphics. One is extremely simple the other somewhat involved.
Here is the simple one:
Simply add this to the top of the Paint event:
float scale = trackBar1.Value / 100f;
if (scale == 0) scale = 1;
e.Graphics.ScaleTransform(scale, scale);

This looks a bit convoluted but the TrackBar will not have a value when the Paint event is called at first.
The Graphics object itself is now scaled and everything you draw with will be scaled.
That was really simple.
One possible issue you may have is that everything, including the width of a Pen will be scaled up or down.
You were going for the more involved way in your question, so let's do that as well..:
First we create a function that scales a point accoding to the TrackBar's Value. Here it is:
PointF scaledPoint(PointF pt, float scale, bool unscale)
{
    if (unscale) return new PointF(pt.X / scale, pt.Y / scale);
    else return new PointF( pt.X * scale, (pt.Y * scale));
}

Two things are worth noting:

The function actually works with PointF not Point. This is really important as the scaling must not lose precision! Going from, say 5 down to 33% and back up again will not go back to 5 but to 3..!
There is an extra parameter that will remove the scaling from a point. We don't need it at the moment; but you will, once you want to catch a point from a MouseClick when the scaling is on!

Now let's use it to scale our point list.
We could do it directly, maybe like this:
for (int p = 0; p < body.Count; p++)
     body[p] = scaledPoint(body[p], scale, false);

While this will work is has a nasty issue: When we move the TrackBar it will reapetedly apply a growing scaling factor. This means that the graphics will get larger faster and faster..not good.
Instead we create a second List<PointF> bodyO with the original point values, which need to maintain..
That means we add points to bodyO but draw with body and scale bodyO to body..:
void scalePoints(float scale)
{
    for (int p = 0; p < body.Count; p++)
        body[p] = scaledPoint(body0[p], scale, false);
}

We call pretty much as in your code:
private void trackBar1_Scroll(object sender, EventArgs e)
{
    scalePoints(trackBar1.Value / 100f);
    panel1.Refresh();
}

Let's see how this works in the Paint event:
private void panel1_Paint(object sender, PaintEventArgs e)
{
    float scale = trackBar1.Value / 100f;
    if (scale == 0) scale = 1;

    bool showGrid = true;  // inserted for testing

    // these graphics work with the scaled points:
    foreach (PointF pt in body) e.Graphics.FillEllipse(Brushes.Red, 
                                  pt.X - 2, pt.Y - 2, scale * 4, scale * 4);
    if (body.Count > 1) e.Graphics.DrawLines(Pens.Black, body.ToArray());

    // here we don't use points but calculate the coordinates, so we need to scale
    for (int x = 0; x < panel1.Width; x += trackBar2.Value)
        for (int y = 0; y < panel1.Height; y += trackBar2.Value)
        {
            if (showGrid == true)
            {
                e.Graphics.FillEllipse(Brushes.Gray, 
                           scale * (x - 2), scale * (y - 2), scale * 4, scale * 4);
            }
            // Point gridpoint = new Point(x, y); // not sure what you do here..?
            // rastr.Add(gridpoint);   // maybe add the point scaled?
        }
}

Note that I scaled the size of the points as well.  Btw, to make both version look all the same you would have to scale the Pen as well:
using (Pen pen = new Pen(somecolor, penWidth * scale))

Finally here is how to add a new Point in the MouseClick:
private void panel1_MouseClick(object sender, MouseEventArgs e)
{
    body0.Add(scaledPoint(e.Location, trackBar1.Value / 100f, true));
    body.Add(e.Location);
    panel1.Invalidate();
}

We add it to the original list bodyO reversing the current scaling and as is, i.e with the current 'pixel size' to the scaled list..

Btw: The many grid points take some time without DoubleBuffering; this creates some flicker.. So either use a Panel subclass with DoubleBuffering:
class DrawPanel : Panel
{ 
   public DrawPanel()
    { DoubleBuffered = true; }
}

Or go for a Picturebox (recommended)!

