使用 PointCollection C# WPF 透支时在 canvas 上扩展多段线
Polylines extended on canvas while overdrawing with use of PointCollection C# WPF
我正在创建 autocad 插件,它从现有几何体中获取点,将其传递给另一个 windows 并在 canvas 上创建与折线具有相同几何体的对象。
Autocad对象是多段线所以有些点(顶点)必须透支。
我从 autocad 收集点、顶点长度并将其转换为 canvas 上真实坐标中的中心对象。然后当我画它时,我得到这个:
我收集的点是正确的,它们是相似的。 canvas 上的绘制代码在这里:
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);
}
当我进入调试器时,点显示如下:
如您所见,点的定义方式正确。
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
Point p = Mouse.GetPosition(canvas);
coords.Content = p.ToString();
}
当我用 mouseMove 读取坐标时,延伸的边长了大约一半长度 (50/2)。
为什么会发生这种情况以及如何解决这个问题?
更新的解决方案:
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 });
我认为这是因为当你从右上角转到中上角时,多边形的绘制超出了实际的点,形成了一种尖锐的顶点。但我认为你在 window 中绘制时 y 轴向下,所以你必须将我的右上角视为底部 :-) 这意味着它是正确的短边。
解决方案是使用不同的线或路径几何:
<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轴向下)。
如果将下面的两个形状插入到 Canvas 中,您将看到多段线和路径的渲染之间的区别。如果您将折线中的值 20 更改为另一个值,您将看到折线(根据设计)呈现的效果 - 与路径相比。我在多段线和路径中的点都是任意的,你应该使用你的 ACad 点。
<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 的更多信息,请查看 here。
更新二:
在后面的代码中,将路径数据构造为字符串可能会非常混乱。相反,您可能想要使用相应的类型:
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;
或者可以从一系列点来完成:
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 中的数据字符串相同。
在这两种情况下,您都需要知道点代表哪种形状,以便您可以相应地设置 isStroked,或者使用其他类型的线段,如弧等。
我最近在使用折线时遇到了同样的问题。通过设置正确的连接类型,我能够摆脱行中不必要的扩展。
您可以将折线的 StrokeLineJoin
属性 设置为 PenLineJoin.Bevel
或 'PenLineJoin.Round'。
poly.StrokeLineJoin = PenLineJoin.Bevel;
或者
poly.StrokeLineJoin = PenLineJoin.Round;
当多段线以锐角转弯时,这将删除锐角。
我正在创建 autocad 插件,它从现有几何体中获取点,将其传递给另一个 windows 并在 canvas 上创建与折线具有相同几何体的对象。 Autocad对象是多段线所以有些点(顶点)必须透支。
我从 autocad 收集点、顶点长度并将其转换为 canvas 上真实坐标中的中心对象。然后当我画它时,我得到这个:
我收集的点是正确的,它们是相似的。 canvas 上的绘制代码在这里:
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);
}
当我进入调试器时,点显示如下:
如您所见,点的定义方式正确。
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
Point p = Mouse.GetPosition(canvas);
coords.Content = p.ToString();
}
当我用 mouseMove 读取坐标时,延伸的边长了大约一半长度 (50/2)。
为什么会发生这种情况以及如何解决这个问题?
更新的解决方案:
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 });
我认为这是因为当你从右上角转到中上角时,多边形的绘制超出了实际的点,形成了一种尖锐的顶点。但我认为你在 window 中绘制时 y 轴向下,所以你必须将我的右上角视为底部 :-) 这意味着它是正确的短边。
解决方案是使用不同的线或路径几何:
<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轴向下)。
如果将下面的两个形状插入到 Canvas 中,您将看到多段线和路径的渲染之间的区别。如果您将折线中的值 20 更改为另一个值,您将看到折线(根据设计)呈现的效果 - 与路径相比。我在多段线和路径中的点都是任意的,你应该使用你的 ACad 点。
<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 的更多信息,请查看 here。
更新二:
在后面的代码中,将路径数据构造为字符串可能会非常混乱。相反,您可能想要使用相应的类型:
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;
或者可以从一系列点来完成:
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 中的数据字符串相同。
在这两种情况下,您都需要知道点代表哪种形状,以便您可以相应地设置 isStroked,或者使用其他类型的线段,如弧等。
我最近在使用折线时遇到了同样的问题。通过设置正确的连接类型,我能够摆脱行中不必要的扩展。
您可以将折线的 StrokeLineJoin
属性 设置为 PenLineJoin.Bevel
或 'PenLineJoin.Round'。
poly.StrokeLineJoin = PenLineJoin.Bevel;
或者
poly.StrokeLineJoin = PenLineJoin.Round;
当多段线以锐角转弯时,这将删除锐角。