似乎你應該實現某種等距算法。假設多邊形線距離每個頂點的距離爲d。算法的步驟是:
- 偏移從其原始位置
- 在d每個多邊形線對於每個頂點畫弧段,其中,所述弧的中心爲頂點和起始點和終止點是連接點線段。
Algorithm for the first step
UPDATE
爲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)));
}
成績
更新非凸多邊形
如果多邊形是非凸的,則不應該添加弧。爲了檢查是否添加弧,我們可以使用凸多邊形的特徵,它的所有頂點都位於二維平面的一邊,由線隔開,由每兩個相鄰頂點定義。 所以,如果多邊形頂點以順時針順序給予,那麼我們就必須檢查下一個點是在右側,只有在這種情況下,劃出一道弧線。
代碼:
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;
}
爲圓角,你可以用'ArcSegments'。鏈接:https://msdn.microsoft.com/en-us/library/system.windows.media.arcsegment(v=vs.110).aspx – Fredrik
希望我的回答幫助。想要補充的是,如果你的多邊形不是凸的,那麼角度> 180的頂點應該被區別對待。如果頂點總是在CW爲了接角很容易通過這個公式http://www.vitutor.com/geometry/vec/angle_vectors.html –
你的回答是偉大的分析。我正試圖將其整合到我的項目中。關於角度,我沒有> 180度,但如果你想要的話,你可以在你的答案中給出一個例子,這對周圍的其他人可能是有用的! :) – FrancescoDS