2011-03-04 37 views
4

如果我有一個封閉的路徑,我可以使用Geometry.GetArea()來近似我的形狀區域。這很棒,爲我節省了很多時間。但是有沒有什麼能幫助我找到一條未封閉的路徑?獲取C#/ WPF中PathGeometry(行)的長度

我現在能夠想出的最好的方法是確保我使用PathGeometry並多次調用GetPointAtFractionLength方法,獲得積分並加起所有這些點之間的距離。

代碼:

public double LengthOfPathGeometry(PathGeometry path, double steps) 
    { 
     Point pointOnPath; 
     Point previousPointOnPath; 
     Point tangent; 

     double length = 0; 

     path.GetPointAtFractionLength(0, out previousPointOnPath, out tangent); 

     for (double progress = (1/steps); progress < 1; progress += (1/steps)) 
     { 
      path.GetPointAtFractionLength(progress, out pointOnPath, out tangent); 
      length += Distance(previousPointOnPath, pointOnPath); 
      previousPointOnPath = pointOnPath; 
     } 
     path.GetPointAtFractionLength(1, out pointOnPath, out tangent); 
     length += Distance(previousPointOnPath, pointOnPath); 

     return length; 
    } 

    public static double Distance(Point p0, Point p1) 
    { 
     return Math.Sqrt((Math.Pow((p1.X - p0.X),2) + Math.Pow((p1.Y - p0.Y),2))); 
    } 

使用(XAML):

<Path Stroke="Beige" StrokeThickness="5" x:Name="Robert"> 
     <Path.Data> 
      <PathGeometry x:Name="Bob"> 
       <PathGeometry.Figures> 
        <PathFigure StartPoint="20,10" IsClosed="False" IsFilled="False"> 
         <PathFigure.Segments> 
          <BezierSegment 
           Point1="100,50" 
           Point2="100,200" 
          Point3="70,200"/> 
          <LineSegment Point="200,300" /> 
          <ArcSegment 
            Size="50,50" RotationAngle="45" 
            IsLargeArc="True" SweepDirection="Counterclockwise" 
          Point="250,150"/> 
          <PolyLineSegment Points="450,75 190,100" /> 
          <QuadraticBezierSegment Point1="50,250" Point2="180,70"/> 
         </PathFigure.Segments> 
        </PathFigure> 
       </PathGeometry.Figures> 
      </PathGeometry> 
     </Path.Data> 
    </Path> 

使用(代碼):

double length = LengthOfPathGeometry(Bob, 10000);

在這個例子中返回結果應該是某處約:1324.37

這似乎工作得很好,但有其缺陷。如果我想爲一個非常大的線更準確的數字,我需要更多的步驟。如果你得到100000步以上,你就會花費很長時間來估算。每個方法調用我的測試機器幾秒鐘。

有沒有人知道更好的方法來近似長度的任何形狀的線?

回答

5

對於快速近似調用GetFlattenedPathGeometry,它會將您的路徑轉換爲一系列直線並累計線長。

這與您現有的代碼幾乎完全相同,除了它更智能地選擇線段(例如,貝塞爾曲線分成的段數取決於曲率),所以您將具有數量級相同準確度的點數較少。

+0

正是我在找的東西。謝謝。 –

2

爲什麼要近似長度?爲什麼不計算實際長度?

PathGeometry包含PathFigures的集合。每個PathFigure包含一個PathSegments(此刻共有7種類型)的集合。您可以遍歷所有內容並計算實際長度並添加它們。

它的一次性投資值得我這麼想。你需要刷一些小小的幾何圖形,但谷歌現在讓一切變得簡單。

+0

如果我需要更準確的數字,這可能是未來的方法。我一直在尋找最簡單的方法來抓住並繼續獲得長度。貝塞爾曲線只能近似,但我相信有更準確和有效的方法來獲得逼近比我的蠻力。 –