使用PointCollection C#WPF重画时在画布上延伸的折线 [英] Polylines extended on canvas while overdrawing with use of PointCollection C# WPF

查看:248
本文介绍了使用PointCollection C#WPF重画时在画布上延伸的折线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建autocad插件,该插件将从现有几何图形获取点,将其传递到另一个窗口,并在画布上创建与折线具有相同几何图形的对象. Autocad对象是折线,因此某些点(顶点)必须重绘.

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.

我从autocad收集点,顶点的长度,并将其转换为画布上真实坐标中的中心对象.然后,当我绘制它时,我得到了:

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();
    }

当我用mouseMove读取坐标时,扩展边的长度大约是长度的一半(50/2).

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?

更新的解决方案:

 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) });

更新了解决方案2 :(更好的解决方案)

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 });

推荐答案

我认为这是因为当您从右上角转到中上角时,多边形的图形会扩展到实际边界附近,从而形成一种尖锐的顶点.但是我认为您在y轴向下的窗口中绘制,因此您必须将我的右上角视为底部rignt :-)这意味着短边是正确的.

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"  />

更新:

参考上面的第一个图,实际上是按以下顺序绘制的:5-6-4-3-1-2. (因为y轴向下).

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).

如果将下面的两个形状插入到画布"中,则会看到折线的渲染和路径之间的区别.如果您在折线中将值20更改为另一个值,则会看到(按设计)折线的渲染效果-与路径相比.我在折线和路径上的点都是任意的,因此,您应该使用ACad点.

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>

如果您想了解有关Path的更多信息,请查看这里.

If you want more information about Path please look here.

更新2:

在后面的代码中,将Path的数据构造为字符串可能会很混乱.相反,您可能要使用相应的类型:

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;

以上内容与MyPath中的数据字符串相同.

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

在这两种情况下,您都需要知道这些点代表哪种形状,以便可以相应地设置isStroked,或者可以使用其他类型的segmen,例如圆弧等.

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.

这篇关于使用PointCollection C#WPF重画时在画布上延伸的折线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆