Getting PathGeometry lengths (lines) in C # / WPF

If I have a closed path, I can use Geometry.GetArea() to approximate the area of ​​my figure. It is great and saves a lot of time. But is there anything around this that will help me find the length of the unclosed path?

The best I could think of was to make sure that I use PathGeometry and repeatedly call the GetPointAtFractionLength method, get the points and add the distance between all these points.

code:

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

code>

Usage (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> 

Usage (code):

double length = LengthOfPathGeometry(Bob, 10000);

In this example, the return result should be somewhere around: 1324.37

This seems to work well, but has its drawbacks. If I want a more accurate number for a very large string, I need more steps. And if you go through more than 100,000 steps, you will have to get close for a long time. A few seconds to call a method on my test machine.

Does anyone know a better way to approach the length of any line shape?

+4
source share
2 answers

For a quick approximation, call GetFlattenedPathGeometry, which converts your path into a series of straight lines and adds line lengths.

This pretty much does the same as your existing code, except that it selects the line segments more intelligently (for example, the number of segments from which the dimensionless curve breaks depends on the curvature), so you will have an order of fewer points with equal accuracy.

+5
source

Why do you want to approximate the length? Why not calculate the actual length?

PathGeometry contains a collection of PathFigures . Each PathFigure contains a collection of PathSegments (a total of 7 types at the moment). You can iterate over everything and calculate the actual lengths and add them.

His one-time investment is worth what I think. You will need to adjust the geometry a bit, but these days Google is doing everything right.

+2
source

Source: https://habr.com/ru/post/1342343/


All Articles