Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move all coordinate from a WPF PolyLine object?

I have a graphic made dynamically with a polyline object. It produces something interesting but I would like to keep only the last 10 coordinates and once we have reach the 10th position, every coordinate would move to the left by X pixel and the new value will be added at the end.

In the Add function of my drawing class I tried this kind of code:

        if (points.Count > 10)
        {
            myPolyline.Points.RemoveAt(0);

            foreach(Point p in myPolyline.Points)
            {
                p.X = p.X - 50;//Move all coord back to have a place for the new one
            }   
        }

That doesn't work because we cannot modify a variable of the collection in a ForEach loop. What is the best way to do this in WPF/C#?

More info

I can do it by doing this:

            for (int i = 0; i < this.myPolyline.Points.Count; i++)
            {
                this.myPolyline.Points[i] = new Point(this.myPolyline.Points[i].X - 50, this.myPolyline.Points[i].Y);
            }

But I would like a cleaner way to do it without having to create point object very time.

like image 256
Patrick Desjardins Avatar asked Feb 28 '23 10:02

Patrick Desjardins


1 Answers

Well, the Point is a struct, so the overhead of creating new ones shouldn't be bad. Doing the following...

Point p = this.myPolyline.Points[i];
p.X -= 50;
this.myPolyline.Points[i] = p;

...would really be no different, simply because structs are passed around by value.

You are pretty much stuck with a for loop and reassigning to myPolyline.Points[i], considering the circumstances:

  1. You have to modify the Point with a different X value.
  2. You can't modify the variable of a foreach loop, so you have to use a for loop.
  3. myPolyline.Points[i].X -= 50 won't work because of the way the Point struct is retrieved from the array and then not re-assigned automatically.

If you simply wanted to move the whole PolyLine, I might have suggested a LayoutTransform or RenderTransform, but you're moving a subset of Points and then will add others.

Edit: If you really want to refactor that operation, you could create an extension method on PointCollection for the for loop and point tweaking like this:

static public void ChangePoints( this PointCollection pc, Vector v ) {
    for (int i = 0; i < pc.Count; i++ ) {
        pc[i] += v;
        // the above works on the indexer because you're doing an operation on the
        // Point rather than on one of the Point's members.
    }
}

Usage:

myPolyline.Points.ChangePoints( new Vector( -50, 0 ) );

You still have to change the Points in the same way, but it's refactored elsewhere so that the usage is more readable. And usage of Vector makes it more readable, too.

like image 114
Joel B Fant Avatar answered Mar 04 '23 10:03

Joel B Fant