首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PathGeometry的非图形用户界面替代方案?

PathGeometry的非图形用户界面替代方案?
EN

Stack Overflow用户
提问于 2012-09-25 16:47:07
回答 3查看 850关注 0票数 5

我有两个巨大的(>100000项) PathGeometry集合,我需要使用PathGeometry.Combine进行比较,如下所示:

代码语言:javascript
复制
List<PathGeometry> firstList;
List<PathGeometry> secondList;
[...]

foreach (PathGeometry pg1 in firstList)
  foreach (PathGeometry pg2 in secondList)
  {
    PathGeometry intergeo = PathGeometry.Combine(pg1, pg2, GeometryCombineMode.Intersect, null);
    if (intergeo.GetArea() > 0)
    {
      // do whatever with intergeo.GetArea()
    }
  }

令我惊讶的是,PathGeometry是图形用户界面的一部分,并且确实使用了调度程序,这有时会导致问题,因为我的计算是在没有使用Parallel.ForEach()的图形用户界面的情况下在后台线程中运行的

所以我正在寻找一种PathGeometry的替代品,它没有连接到图形用户界面。

我的数字相当复杂,并且在PathGeometry.Figures中添加了很多PathFigures。

我自己从一些臃肿的政府xml文件中创建了这些PathGeometries,所以创建其他文件不成问题。但我需要一个函数来创建其中两个几何图形的交集(而不是将它们彼此相加),以获得两个几何图形覆盖的区域,如下图中的红色区域:

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-27 23:01:15

System.Windows.Media还包含一个类StreamGeometry,它是PathGeometry的“轻量级替代品”。它不支持数据绑定、动画或修改,但是因为它是从Geometry派生的,所以它应该有一个Combine方法。

请参阅StreamGeometry @ MSDN

票数 3
EN

Stack Overflow用户

发布于 2012-09-26 00:08:25

使用the geometry "mini-langauge"而不是PathGeometry对象将Path.Data解析为字符串怎么样?

例如,与其创建如下所示的内容:

代码语言:javascript
复制
<Path Stroke="Black">
    <Path.Data>
        <PathGeometry>
            <PathFigure IsClosed="true" StartPoint="10,100">
                <LineSegment Point="100,100" />
                <LineSegment Point="100,50" />
            </PathFigure>
        </PathGeometry>
    </Path.Data>
</Data>

你可以创建

代码语言:javascript
复制
<Path Stroke="Black" Data="M 10 100 L 100 100 L 100 50 Z" />

或者,在您的示例中,XAML可能如下所示:

代码语言:javascript
复制
<Path Stroke="Black" Data="{Binding MyPathProperty}" />

Path.Data是一个预期采用特定格式的字符串,是绘制路径几何图形的一种较短的方法。

下面是从上面的链接中获取的字母含义和预期参数的列表:

  • F值-设置Geometry.FillRule属性。使用0表示EvenOdd,或使用1表示NonZero。此命令必须出现在字符串的开头(如果您决定使用它)。
  • M x,y-为几何图形创建新的PathFigure并设置其起点。此命令必须在除F之外的任何其他命令之前使用。但是,您也可以在绘图序列中使用此命令来移动坐标系的原点。(M代表移动)。
  • L x,y-创建指向指定点的半径。
  • H x-使用指定的X值并保持Y值不变来创建水平LineSegment。
  • V y-使用指定的Y值并保持X值不变来创建垂直LineSegment。
  • A LineSegment x,radiusY,degrees isLargeArch,isClockwise x,y-创建指向指定点的ArcSegment。您可以指定描述圆弧的椭圆的半径、圆弧旋转的度数以及设置IsLargeArc和SweepDirection的布尔标志properties.
  • C x1,y1 x2,y2 x,y-使用(x1,y1)和(x2,y2 )处的控制点创建指向指定点的BezierSegment。
  • q x1,y1 x,y-创建指向指定点的QuadraticBezierSegment,其中一个控制点位于(x1,y1)。S,x,Y-通过将上一个BezierSegment.
  • Z中的第二个控制点用作新BezierSegment中的第一个控制点来创建平滑BezierSegment -结束当前PathFigure并将IsClosed设置为true。如果不想将IsClosed设置为true,则不需要使用此命令-如果要开始新的PathFigure或结束字符串,只需使用M即可。

例如,上面示例中使用的字符串(M 10 100 L 100 100 L 100 50 Z)可以分解为:

  • M 10 100 -起始路径位于10, 100
  • L 100 100 -绘制直线至100,100
  • L 100 50 -绘制直线至100,50
  • Z - End String

在从数据库读取Path.Data的情况下,首先要创建一个包含M x y的字符串,其中x y是路径的x,y起始位置,然后一次读取一个数据段,并使用上面的速记将它们追加到字符串中,最后使用Z结束字符串

请注意,大写字母和小写字母有不同的含义。大写字母表示为路径段提供绝对值,而小写字母表示路径段应相对于最后一个段。

例如,如果您的线段显示为"L 10 10",则表示在网格上的位置10,10绘制一条线,而"l 10 10"表示从当前位置向上绘制一条线10,并从当前位置向右绘制10条线。

在从数据库读取PathGeometry的情况下,需要将每个PathGeometry转换为字符串,然后组合这些字符串。

这里有一些粗略的代码作为示例。我知道它不起作用,但希望它能为你指明正确的方向

编辑

根据您编辑的问题,您的数据项听起来像是存储为PathGeometry,因此您可能需要将PathGeometry对象转换为字符串,然后组合这些字符串

这里有一个非常粗略的例子。我相当确定我有一些语法错误,可能还有一点逻辑错误,因为我不太熟悉PathGeometry对象,但希望它能为您指明正确的方向

代码语言:javascript
复制
foreach (PathGeometry pg1 in firstList)
    foreach (PathGeometry pg2 in secondList)
    {
        var s1 = ConvertGeometryToString(pg);
        var s2 = ConvertGeometryToString(pg2);

        // Ideally you probably wouldn't want this until you have your 
        // full PathGeometry string built, but I'm not sure what you're doing
        // with the object so left it in anyways
        PathGeometry intergeo = Geometry.Parse(s1 + s2);

    }
}


string ConvertGeometryToString(PathGeometry pg)
{
    StringBuilder sb = new StringBuilder();

    foreach(var figure in pg.PathFigures)
    {
        sb.Append("M " + figure.StartPoint);

        foreach(var seg in figure.Segments)
        {
            if (seg is LineSegment)
                sb.Append(" L " + ((LineSegment)seg).Point);

            else if (seg is ArcSegment)
            ... etc

        }

        if (figure.IsClosed)
            sb.Append(" Z");
    }

    return sb.ToString();
}
票数 3
EN

Stack Overflow用户

发布于 2012-09-27 20:51:48

我刚刚试用过它,但是NetTopologySuite看起来可以做你想要的事情。

下面的代码创建两个多边形,检查它们是否相交,找到它们的面积并计算它们的交点。

代码语言:javascript
复制
var gf = new GeometryFactory();

var c1 = new[] { new Coordinate(0, 0), new Coordinate(2, 0),
                 new Coordinate(2, 2), new Coordinate(0, 2),
                 new Coordinate(0, 0) };
var lr1 = gf.CreateLinearRing(c1);
var p1 = gf.CreatePolygon(lr1, new ILinearRing[0]);

var c2 = c1.Select(c => new Coordinate(c.X + 1, c.Y + 1)).ToArray();
var lr2 = gf.CreateLinearRing(c2);
var p2 = gf.CreatePolygon(lr2, new ILinearRing[0]);

var intersects = p1.Intersects(p2);        // true
var intersection = p1.Intersection(p2);    // another polygon
var area = intersection.Area;              // 1.0
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12579294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档