Polylines extended on canvas while overdrawing with use of PointCollection C# WPF

我怕爱的太早我们不能终老 提交于 2020-03-06 07:31:21

问题


I am creating autocad plugin which get points from existing geometry, pass it to another windows and create object with same geometry on canvas as polyline. Autocad object is polyline so some points (vertices) must be overdrawn.

I gather points from autocad, length of vertices and transform that to center object in real coordinates on canvas. Then when I draw it, i get this:

The points that i collect are correct, they are transformed simetrically. And the code for drawing on canvas is here:

 private void drawOnCanvas(List<Point> points)
    {
        // Create a black Brush
        SolidColorBrush blackBrush = new SolidColorBrush();
        blackBrush.Color = Colors.Black;

        // Create a polyline
        Polyline poly = new Polyline();
        poly.Stroke = blackBrush;
        poly.StrokeThickness = 4;

        // Create a collection of points for a polyline
        PointCollection polygonPoints = new PointCollection();
        for (int i = 0; i < points.Count-1; i++)
        {
            polygonPoints.Add(points[i]);
        }

        // Set Polyline.Points properties
        poly.Points = polygonPoints;

        // Add polyline to the page
        canvas.Children.Add(poly);
    }

When i enter debugger, points are displayed like this:

As you see, points are defined in the right way.

private void canvas_MouseMove(object sender, MouseEventArgs e)
    {
        Point p = Mouse.GetPosition(canvas);
        coords.Content = p.ToString();
    }

When I read coordinates with mouseMove, extended side is longer for about half of length (50/2).

Why does this happen and how to fix this problem?

Updated Solution:

 for (int i = 0; i < points.Count - 1; i += 2)
                {
                    pathGeometry = pathGeometry + "M" + points[i].X.ToString("F2") + " " + points[i].Y.ToString("F2") + " " + "L" + points[i + 1].X.ToString("F2") + " " + points[i + 1].Y.ToString("F2") + " ";
                }

                canvas.Children.Add(new Path { Stroke = Brushes.Brown, StrokeThickness = 3, Data = Geometry.Parse(pathGeometry) });

Updated Solution 2: (beter solution)

PathFigure figures = new PathFigure();
figures.StartPoint = points[0];
points.RemoveAt(0);
figures.Segments = new PathSegmentCollection(points.Select((p, i) => new LineSegment(p, i % 2 == 0)));
PathGeometry pg = new PathGeometry();
pg.Figures.Add(figures);
canvas.Children.Add(new Path { Stroke = Brushes.Brown, StrokeThickness = 3, Data = pg });

回答1:


I think it's because when you turn from the top right point to the top middle point the drawing of the polygon is extended beyound the actual point to make a kind of sharp vertex. But I think you draw in the window with y-axis downwards so you'll have to think my top right as bottom rignt :-) It means it's the short sides that are right.

The solution is to use distinct lines or a pathgeometry:

<Path Data="M10 5 L60 5 M35 5 L35 65 M10 65 L60 65" Stroke="Black" StrokeThickness="5"  />

Update:

With reference to the first drawing above, it is actually drawn in this sequence: 5-6-4-3-1-2. (because y-axis is downwards).

If you insert the two shapes below into a Canvas, you'll see the difference between the rendering of a polyline and a path. If you change the value 20 to another value in the Polyline you'll see the effect of the (per design) rendering of a Polyline - compared to the Path. My points in both polyline and path are arbitrary, you should of cause use your ACad points instead.

<Polyline Name="Poly" Points="10 5, 60 5, 35, 20 35, 65, 10, 65 60, 65" Stroke="Blue" StrokeThickness="5">
</Polyline>

<Path Name="MyPath" Data="M10 5 L60 5 M35 5 L35 65 M10 65 L60 65" Stroke="Black" StrokeThickness="5">
  <Path.RenderTransform>
    <TranslateTransform X="0" Y="100" />
  </Path.RenderTransform>
</Path>

If you want more information about Path please look here.

Update 2:

In code behind it can be quite messy to construct the Data of the Path as a string. Instead you may want to use the corresponding types:

  PathFigure figures = new PathFigure(new Point(10, 5),
    new PathSegment[]
    {
      new LineSegment(new Point(60,5), true),
      new LineSegment(new Point(35,5), false),
      new LineSegment(new Point(35,65), true),
      new LineSegment(new Point(10,65), false),
      new LineSegment(new Point(60,65), true),
    }, false);

  PathGeometry pg = new PathGeometry();
  pg.Figures.Add(figures);
  MyPath.Data = pg;

Or it can be done from a sequence of points:

  Point[] points =
  {
    new Point(60, 5),
    new Point(35, 5),
    new Point(35, 65),
    new Point(10, 65),
    new Point(60, 65),
  };

  PathFigure figures = new PathFigure();
  figures.StartPoint = new Point(10, 5);
  figures.Segments = new PathSegmentCollection(points.Select((p, i) => new LineSegment(p, i % 2 == 0)));
  PathGeometry pg = new PathGeometry();
  pg.Figures.Add(figures);
  MyPath.Data = pg;

The above does the same as the Data-string in MyPath.

In both cases you'll need to know which kind of shape the points represent so you can set the isStroked accordingly, or maybe use other types of segmens like arcs etc.




回答2:


I had faced the same issue recently, while using Polylines. I was able to get rid of the unnecessary extensions in the lines by setting the correct Join type.

You could set the StrokeLineJoin property of the Polyline to either PenLineJoin.Bevel or 'PenLineJoin.Round'.

poly.StrokeLineJoin = PenLineJoin.Bevel;

Or

poly.StrokeLineJoin = PenLineJoin.Round;

This would remove the sharp vertex when the Polylines turn at an acute angle.



来源:https://stackoverflow.com/questions/40302791/polylines-extended-on-canvas-while-overdrawing-with-use-of-pointcollection-c-sha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!