2011-03-04 4 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 단계를 넘으면, 당신은 대략적으로 오랜 시간이 걸립니다. 테스트 머신에서 메소드 호출 당 2 초.

누구든지 선의 모양을 대략적으로 계산하는 더 좋은 방법을 알고 있습니까?

답변

5

경로를 일련의 직선으로 변환하고 선 길이를 더하는 GetFlattenedPathGeometry를 더 빨리 근사값으로 호출하십시오.

이것은 기존 코드와 똑같은 일을합니다 (예 : 베 지어 곡선이 분할되는 세그먼트 수는 곡률에 따라 다름). 따라서 선분을보다 지능적으로 선택한다는 점을 제외하고는 같은 정확도에 대한 점수가 적습니다.

+0

정확히 내가 무엇을 찾고 있었습니까. 고맙습니다. –

2

왜 길이를 대략적으로 계산 하시겠습니까? 왜 실제 길이를 계산하지 않습니까?

PathGeometry에는 PathFigures의 모음이 포함되어 있습니다. 각 PathFigure는 PathSegments (현재 총 7 가지 유형)의 콜렉션을 포함합니다. 모든 것을 반복하고 실제 길이를 계산하여 추가 할 수 있습니다.

그럴 가치가있는 일회성 투자입니다. 당신은 작은 기하학을 솔질해야하지만 구글은 요즘 쉽게 모든 것을 만듭니다.

+0

앞으로 더 정확한 숫자가 필요할 경우 이동하는 방법이 될 수 있습니다. 나는 방금 길이를 얻는 가장 간단한 방법을 찾고 있었다. 베 지어 곡선은 근사치 일 수 있지만, 근사치를 얻는 정확하고 효율적인 방법이 내 짐작보다는 더 확실합니다. –