如何知道一个StreamGeometry是一条线
本文关键字:StreamGeometry 一条 一个 何知道 | 更新日期: 2023-09-27 18:17:18
我有一个集合的StreamGeometrys。每个StreamGeometry可以是任何形状。我只想拿起StreamGeometrys,它们是线。我怎么知道一个StreamGeometry是一条线。
背景:我从一个接口得到StreamGeometrys的集合。接口是由其他团队提供的,不返回几何是什么的信息。(我可能会与他们讨论进行更新,但这涉及架构更改。)我有一个函数来分组几何,并得到组的轮廓。最初,我将它们添加到一个GeometryGroup中,然后我使用Geometry。GetOutlinedPathGeometry获取几何组的轮廓。行为良好。
问题:但是当Geometrys的数量增加到超过200时,GetOutlinedPathGeometry变得非常慢。
当前解决方案:那么我必须做出妥协,得到一个不那么准确的大纲。我使用的不是GetOutlinedPathGeometry,而是Geometry。组合以组合几何。几何学。Combine主要用于封闭几何。当一个几何图形不闭合时,它会找到最近的点使其闭合。这种行为在某种程度上降低了整体轮廓的复杂性,GetOutlinedPathGeometry可以更快地获得结果。
我如何得到这个问题:但一个问题是几何。合并将忽略线形。合并所有几何后,线不在组中。我想找到那些线,然后使用GetOutlinedPathGeometry首先获得它们的轮廓。然后用他们的轮廓与其他的相结合。
还有,即使我有几何类型信息,它也不能帮助太多。因为几何。"组合"将忽略可以由任何几何类型构成的任何线形。直线,路径甚至矩形都可以做成直线。
其他尝试:我尝试使用GetOutlinedPathGeometry首先获得每个几何形状的轮廓,然后组合。性能有所提高,但仍然很慢。
只需放入这段代码,您就可以使用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>
在i74790上我得到了这些时间:
80µs - False
390µs - True
86µs - False
82µs - False
69µs - False
355µs - True