如何知道StreamGeometry是一条线

时间:2016-11-10 08:05:15

标签: c# wpf

我有StreamGeometrys的集合。每个StreamGeometry都可以是任何形状。我只想拿起作为线条的StreamGeometrys。我怎么知道StreamGeometry是一条线。

背景 我从界面中收集了StreamGeometrys。界面由其他团队提供,并且不会返回几何图形的信息。 (我可以与他们讨论进行更新,但它涉及架构更改。)我有一个功能,可以对Geometrys进行分组并获得组的轮廓。最初,我将它们添加到GeometryGroup,然后我使用Geometry.GetOutlinedPathGeometry来获取GeometryGroup的轮廓。行为很好。

问题:但当Geometrys数量增加到200以上时,GetOutlinedPathGeometry变得非常慢。

当前的解决方案:然后我必须妥协以获得不准确的大纲。我使用Geometry.Combine来组合Geometrys而不是GetOutlinedPathGeometry。 Geometry.Combine主要用于闭合几何。如果未关闭几何体,它将找到最近的点以使其关闭。此行为以某种方式降低了整体轮廓的复杂性,GetOutlinedPathGeometry可以更快地获得结果。

我如何解决这个问题:但有一个问题是Geometry.Combine会省略Line Shapes。合并所有Geometrys后,Line不在组中。所以我想找到那些线并使用GetOutlinedPathGeometry来首先获得它们的轮廓。然后使用他们的轮廓与其他人结合。

同样,即使我有Geometry类型的信息,它也无济于事。因为Geometry.Combine将省略任何可以由任何几何类型组成的线形。线条,路径甚至矩形都可以形成线条形状。

其他尝试:我尝试先使用GetOutlinedPathGeometry来获取每个几何体的轮廓,然后再进行组合。性能有所改善,但仍然很慢。

1 个答案:

答案 0 :(得分:1)

只需删除此代码,您就可以使用StreamGeometry.IsLine()来检查行。

public static class StreamGeometryExtensions
{
    public static bool IsLine(this StreamGeometry sg, double sampleRate = 0.2, decimal tolerance = 0
    {
        PathGeometry g = sg.GetFlattenedPathGeometry();
        if (g.MayHaveCurves())
        {
            return false;
        }

        Point origin, originTangent;
        Point end, endTangent;
        g.GetPointAtFractionLength(0, out origin, out originTangent);
        g.GetPointAtFractionLength(1, out end, out endTangent);

        Vector originToEnd = end - origin;

        for (double i = 0; i < 1; i += sampleRate)
        {
            Point current, currentTangent;
            g.GetPointAtFractionLength(i, out current, out currentTangent);

            Vector currentToEnd = end - current;
            Vector originTocurrent = current - origin;

            decimal l1 = (decimal)(originTocurrent.Length + currentToEnd.Length);
            decimal l2 = (decimal)originToEnd.Length;

            if (Math.Abs(l2 - l1) > (l2 * tolerance))
            {
                return false;
            }
        }
        return true;
    }
}

代码每隔X%“采样”一次路径(示例0.2 = 20%)并检查原点,结束点和当前采样点是否在一条线上。

代码是解决问题的非常通用的解决方案,可以针对性能非常重要的特定场景进行优化。

我测量了以下路径的性能:(sampleRate = 0.2,tolerance = 0)

    <Path Data="M 217,172 L 10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300"></Path>
    <Path Data="M 217,172 L 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20"></Path>
    <Path Data="M 217,172 L 10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300"></Path>
    <Path Data="M 217,172 L 10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300"></Path>
    <Path Data="M 217,172 L 10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300,  10 50, 50 30, 70 40, 100 300 10 50, 50 30, 70 40, 100 300"></Path>
    <Path Data="M 217,172 L 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20, 20 20"></Path>

在i7 4790上我得到了这些时间:

80µs - False
390µs - True
86µs - False
82µs - False
69µs - False
355µs - True
相关问题