Non GUI alternative for PathGeometry?

I have two huge (> 100,000 elements) PathGeometry collections that I need to compare using PathGeometry.Combine something like this:

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

To my surprise, PathGeometry is part of the graphical user interface and uses a dispatcher, which sometimes causes problems, because my calculations are performed in some background thread without a GUI using Parallel.ForEach ()

So I'm looking for an alternative to PathGeometry that is not GUI related.
My numbers are quite complex and add a lot of PathFigures to PathGeometry.Figures.

PathGeometries XML , - . , ( ), , , :

enter image description here

+5
3

System.Windows.Media StreamGeometry, " " PathGeometry. , , Geometry, Combine.

. StreamGeometry @MSDN

+3

Path.Data , "-langauge" PathGeometry?

, - :

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

<Path Stroke="Black" Data="M 10 100 L 100 100 L 100 50 Z" />

XAML, , :

<Path Stroke="Black" Data="{Binding MyPathProperty}" />

Path.Data - , , , .

, :

  • F - Geometry.FillRule. 0 EvenOdd 1 NonZero. ( ).

  • M x, y - PathFigure . , F. , . ( ).

  • L x, y - LineSegment .

  • H x - LineSegment, X Y.

  • V y - LineSegment, Y X.

  • x, radiusY, isLargeArch, isClockwise x, y - ArcSegment . , , , IsLargeArc SweepDirection .

  • C x1, y1 x2, y2 x, y - BezierSegment , (x1, y1) (x2, y2).

  • Q x1, y1 x, y - Bezier ​​(x1, y1).

  • S x2, y2 x, y - BezierSegment, BezierSegment BezierSegment.

  • Z - PathFigure IsClosed true. , IsClosed true - M, PathFigure .

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

, Path.Data , , M x y, x y - x, y , , , Z

, . , , , .

, "L 10 10", , 10,10 , "L 10 10" 10 10 .

, PathGeometry , PathGeometry , .

. , , , , .

Edit

, PathGeometry, PathGeometry ,

. , , , , PathGeometry, , ,

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

, NetTopologySuite , , .

, , , .

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

All Articles