在我的WPF项目中,我想绘制一些多边形或折线。它们需要是具有圆角的多边形,这些多边形在给定的顶点之外传递,如下图所示:
还需要在第一个点(多边形的左上角)中有一个钩子,但主要问题是关于在给定点之外传递。
例如,如果点具有给定的坐标:
P1(10,10)
P2(10100)
P3(100,100)
P4(100,10)
如何创建多边形?
我找到了一个例子here但是给出的顶点在形状之外而不在其中。
有没有办法在WPF中构建这种形状?无论是图书馆还是本地代码。
答案 0 :(得分:1)
似乎你应该实现某种等距算法。假设多边形线与每个顶点的距离 d 。算法步骤是:
<强>更新强>
创建示例代码以说明algorythm。
<强> XAML 强>
<Canvas Name="canvas">
<Polygon Name="poly" Stroke="Black" >
<Polygon.Points>
<Point X="110" Y="110" />
<Point X="110" Y="200" />
<Point X="200" Y="200" />
<Point X="300" Y="110" />
<Point X="200" Y="110" />
</Polygon.Points>
</Polygon>
</Canvas>
<强> C#强>
double _distance = 10.0;
Line CreateLine(Point pointStart, Point pointEnd)
{
Line line = new Line();
line.Stroke = Brushes.Red;
line.X1 = pointStart.X;
line.Y1 = pointStart.Y;
line.X2 = pointEnd.X;
line.Y2 = pointEnd.Y;
return line;
}
Path CreateArc(Point pointStart, Point pointEnd, double radius)
{
ArcSegment arc = new ArcSegment();
arc.Point = pointEnd;
arc.Size = new Size(radius, radius);
var pathFigure = new PathFigure(pointStart, new PathSegment[] { arc }, false);
Path path = new Path();
path.Data = new PathGeometry(new PathFigure[] { pathFigure });
path.Stroke = Brushes.Red;
return path;
}
private void CreateDrawing()
{
for (int i = 0; i < poly.Points.Count; i++)
{
int lastPointIndex = (i > 0) ? i - 1 : poly.Points.Count - 1;
int nextPointIndex = (i < poly.Points.Count - 1) ? i + 1 : 0;
var pointsPair = GetPerpendicularPoint(poly.Points[i].X, poly.Points[i].Y, poly.Points[nextPointIndex].X, poly.Points[nextPointIndex].Y, _distance);
var lastPointsPair = GetPerpendicularPoint(poly.Points[lastPointIndex].X, poly.Points[lastPointIndex].Y, poly.Points[i].X, poly.Points[i].Y, _distance);
canvas.Children.Add(CreateLine(pointsPair.Item1, pointsPair.Item2));
canvas.Children.Add(CreateArc(lastPointsPair.Item2, pointsPair.Item1, _distance));
}
}
private Tuple<Point, Point> GetPerpendicularPoint(double startX, double startY, double stopX, double stopY, double distance)
{
Point p = new Point(startX - stopX, startY - stopY);
Point n = new Point(p.Y, -p.X);
double norm_length = Math.Sqrt((n.X * n.X) + (n.Y * n.Y));
n.X /= norm_length;
n.Y /= norm_length;
return new Tuple<Point, Point>(new Point(startX + (distance * n.X), startY + (distance * n.Y)), new Point(stopX + (distance * n.X), stopY + (distance * n.Y)));
}
<强>结果
非凸多边形的更新
如果多边形是非凸的,则不应添加弧。为了检查是否添加弧,我们可以使用凸多边形的特征,它的所有顶点都在2D平面的一侧除以线,由每两个相邻顶点定义。 因此,如果以时钟顺序给出多边形顶点,那么我们必须检查下一个点是否在右侧,并且仅在这种情况下绘制弧。
代码:
if (IsRight(poly.Points[lastPointIndex], poly.Points[i], poly.Points[nextPointIndex]))
{
canvas.Children.Add(CreateArc(lastPointsPair.Item2, pointsPair.Item1, _distance));
}
...
public bool IsRight(Point a, Point b, Point c)
{
return ((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X)) > .0;
}