我正在创建autocad插件,它从现有几何体获取点,将其传递到另一个窗口,并在画布上创建与折线相同几何体的对象。 Autocad对象是折线,因此一些点(顶点)必须透支。
我从autocad收集点,顶点长度,并将其转换为画布上实际坐标中的中心对象。然后当我画它时,我明白了:
我收集的点是正确的,它们是通过模拟转换的。在画布上绘图的代码在这里:
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 });
答案 0 :(得分:1)
我认为这是因为当你从右上角转到顶部中间点时,多边形的绘图会延伸到实际点以形成一个尖锐的顶点。但我认为你在窗口画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轴向下)。
如果将下面的两个形状插入到画布中,您将看到折线和路径的渲染之间的差异。如果将值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。
更新2:
在后面的代码中,将Path的数据构造为字符串可能会非常混乱。相反,您可能想要使用相应的类型:
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,或者使用其他类型的segmens,如arcs等。
答案 1 :(得分:0)
我最近在使用Polylines时遇到了同样的问题。通过设置正确的Join类型,我能够摆脱行中不必要的扩展。
您可以将折线的StrokeLineJoin
属性设置为PenLineJoin.Bevel
或'PenLineJoin.Round'。
poly.StrokeLineJoin = PenLineJoin.Bevel;
或者
poly.StrokeLineJoin = PenLineJoin.Round;
当折线以锐角转动时,这将消除尖锐的顶点。