简体   繁体   English

在C#/ WPF中获取PathGeometry(行)的长度

[英]Getting length of a PathGeometry (lines) in C#/WPF

If I have a closed path, I can use Geometry.GetArea() to approximate the area of my shape. 如果我有一个封闭的路径,我可以使用Geometry.GetArea()来近似我的形状区域。 This is great and saves me a lot of time. 这很棒,节省了我很多时间。 But is there anything around that will help me find the length of a unclosed path? 但周围有什么可以帮助我找到一条未封闭路径的长度吗?

The best I've been able to come up with for now is to make sure I am using PathGeometry and call the GetPointAtFractionLength method multiple times, get the points and add up the distance between all those points. 我现在能够想出的最好的方法是确保我使用PathGeometry并多次调用GetPointAtFractionLength方法,得到点并加上所有这些点之间的距离。

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

Usage (XAML): 用法(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);

For this example the result returned should be somewhere around: 1324.37 对于此示例,返回的结果应该在某处:1324.37

This seems to work out fine, but has its flaws. 这看起来很好,但有其缺陷。 If I want a more accurate number for a very large line, I need more steps. 如果我想要一个非常大的线的更准确的数字,我需要更多的步骤。 And if you get above 100000 steps, you run into a long time to approximate. 如果你达到100000步以上,你会遇到很长时间的近似。 A couple of seconds per method call on my test machine. 在我的测试机器上每个方法调用几秒钟。

Does anyone know a better way to approximate a length of any shape of line? 有没有人知道更接近任何形状线的长度的方法?

For a quicker approximation call GetFlattenedPathGeometry, which will convert your path to a series of straight lines, and add up the line lengths. 要获得更快的近似值,请调用GetFlattenedPathGeometry,它将您的路径转换为一系列直线,并将线长相加。

This is pretty much doing the same thing as your existing code except that it selects the line segments more intelligently (eg the number of segments a bezier curve is split into depends on the curvature) so you'll have orders of magnitude fewer points for the same accuracy. 这与现有代码完全相同,只是它更智能地选择线段(例如,贝塞尔曲线被分割成的线段数取决于曲率),因此您的点数将减少几个数量级。精度相同。

Why do you want to approximate the length? 你为什么要近似长度? Why not calculate the actual length? 为什么不计算实际长度?

A PathGeometry contains a collection of PathFigures . PathGeometry包含PathFigures的集合。 Each PathFigure contains a collection of PathSegments (7 types in total at the moment). 每个PathFigure都包含一个PathSegments集合(目前共有7种类型)。 You can iterate over everything and calculate the actual lengths and add them up. 您可以迭代所有内容并计算实际长度并将其相加。

Its a one time investment worth doing I think. 我认为这是一次性投资。 You'll need to brush up a little geometry but Google makes everything easy these days. 你需要刷一点几何,但谷歌这些日子让事情变得简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM