2016-02-16 47 views
0

在我的WPF項目中,我想繪製一些多邊形或多段線。他們需要的多邊形帶圓角通過外部給予頂點如下面的圖像例如: image samplewpf c#在頂點周圍創建多邊形

它也需要有在所述第一點(左上多邊形的)的鉤,但主要問題是關於通過給定點以外的問題。

例如,如果點具有給定的座標:

P1(10,10)

P2(10,100)

P3(100,100)

P4(100,10 )

如何創建多邊形?

我找到了一個例子here,但給出的頂點是在形狀之外,不在其內部。

有沒有辦法在WPF中建立這種形狀?無論它是一個庫還是本地代碼。

+0

爲圓角,你可以用'ArcSegments'。鏈接:https://msdn.microsoft.com/en-us/library/system.windows.media.arcsegment(v=vs.110).aspx – Fredrik

+0

希望我的回答幫助。想要補充的是,如果你的多邊形不是凸的,那麼角度> 180的頂點應該被區別對待。如果頂點總是在CW爲了接角很容易通過這個公式http://www.vitutor.com/geometry/vec/angle_vectors.html –

+0

你的回答是偉大的分析。我正試圖將其整合到我的項目中。關於角度,我沒有> 180度,但如果你想要的話,你可以在你的答案中給出一個例子,這對周圍的其他人可能是有用的! :) – FrancescoDS

回答

1

似乎你應該實現某種等距算法。假設多邊形線距離每個頂點的距離爲d。算法的步驟是:

  1. 偏移從其原始位置
  2. 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))); 
    } 

成績

simple equidistant

更新非凸多邊形

如果多邊形是非凸的,則不應該添加弧。爲了檢查是否添加弧,我們可以使用凸多邊形的特徵,它的所有頂點都位於二維平面的一邊,由線隔開,由每兩個相鄰頂點定義。 所以,如果多邊形頂點以順時針順序給予,那麼我們就必須檢查下一個點是在右側,只有在這種情況下,劃出一道弧線。

代碼:

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