2011-03-04 15 views
4

閉じたパスがある場合は、Geometry.GetArea()を使用してシェイプの面積を近似できます。これは素晴らしいことですし、私に多くの時間を節約します。しかし、閉鎖されていない道のりの長さを見つけるのに役立つものがありますか?C#/ WPFのPathGeometry(lines)の長さの取得

今のところ、私が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種類あります)。すべてを繰り返し処理し、実際の長さを計算して追加することができます。

私は考える価値があると思います。小さなジオメトリを磨く必要がありますが、Googleは最近、すべてを簡単にしています。

+0

もっと正確な数字が必要な場合、これは将来的に移動する方法かもしれません。私はちょうど長さを取得し、取得するための最も簡単な方法を探していた。ベジェ曲線は近似することしかできませんが、近似を得るためのより正確で効率的な方法が私のブルートフォースよりも確実です。 –

関連する問題