0

I've got two geometrical data sets to match, both containing tens of thousands PathGeometries. To be exact I need to find areas which overlap from one set to the other, so I got a loop like

foreach (var p1 in firstGeometries)
{
  foreach (var p2 in secondGeometries)
  {
      PathGeometry sharedArea = PathGeometry.Combine(p1, p2, GeometryCombineMode.Intersect, null);
      if (sharedArea.GetArea() > 0) // only true 0.01% of the time
      {
        [...]
      }
  }
}

Now, due to the nature of my data, 99,99% of the times the combinations do not intersect at all. Profiling told me this is the most 'expensive' part of this calculation.

Is there any way to speed up or get a faster collision detection between two PathGeometries?

Sam
  • 28,421
  • 49
  • 167
  • 247
  • 1
    Are your PathGeometries of the same kind? (I mean all rectangles, all circles, etc.) – as-cii Oct 07 '11 at 11:36
  • Sadly no. They represent real geodata. Mostly they are polygons, some may contain part circles or even more complex stuff. – Sam Oct 07 '11 at 11:54

5 Answers5

2

Adding a new answer since I'm more familiar with the Geometry class now. First, I'd test for intersection using their bounding boxes. Though honestly, PathGeometry.Combine probably already does this. So what's the real problem? That testing the boundary of each object against the boundary of every other object is quadratic time. If you instead found intersections (or collisions in some areas of CS) using a quadtree, you could have significant performance gains. Hard to say without testing and fine tuning though. http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/

Brent
  • 4,153
  • 4
  • 30
  • 63
1

Maybe you can use the Parallel.ForEach method, if you have more than one cpu core avaiable.

Aykut Çevik
  • 2,060
  • 3
  • 20
  • 27
  • 1
    This would be my next approach after speeding comparison up, yes. But since these datasets are huge I need to check other possibilities, too. – Sam Oct 07 '11 at 11:37
  • I don't think Parallelizing will give significant improvement on running time, since the bottleneck is hugely Comparison based. – Shamim Hafiz - MSFT Oct 07 '11 at 11:43
  • 1
    Actually comparison could be parallized very nicely. Why should it not, it's fully CPU-based. – Sam Oct 10 '11 at 12:24
0

I haven't tested it, but it may be helpful to use GetFlattenedPathGeometry and combine the results of that instead. Depending on the type of geometry your combining, it's likely getting converted to a polygonal approximation each time. Using GetFlattenedPathGeometry ahead of time will hopefully eliminate the redundant computation.

Brent
  • 4,153
  • 4
  • 30
  • 63
0

You definitely need a "broad and narrow phase" to do this. Bounding-Box checks are a must for something like this. A much simpler alternative to a quad tree would be to use "spatial hashing" (sometimes also called "spatial indexing"). This technique should reduce the needed time a thousandfold. For a reference use: http://www.playchilla.com/as3-spatial-hash It's in AS3 but it's trivial to convert it to C#

Riki
  • 1,776
  • 1
  • 16
  • 31
0

Though I am not sure about the exact nature of each of the path geometry, but assuming that they are polygons:

You can sort each object based on their bounds. This way, you are assured that, once the condition if (sharedArea.GetArea() > 0) fails, the remaining elements in the inner loop will not produce an area greater than 0, so you can break out of the loop.

It will significantly improve the running time, since the condition is likely to fail most of the time.

Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • I would need to take into account both x and y coordinates to make this work. When only using left point (x) the areas might not overlap due to y coordinate, so the condition failing does not mean there are no more shared areas. – Sam Oct 07 '11 at 11:58
  • 1
    In short: it won't work since the data has 2 dimensions, not 1. – Sam Oct 07 '11 at 12:05
  • 1
    And at least you got me the idea to store the left and right extent of the geometries, sort them and know using the extent if Combining can be ignored, which might speed things up quite nicely. Thanks! – Sam Oct 07 '11 at 12:12
  • I actually overlooked the part about y-axis. At least, sorting by the extreme x value can give some improvement. – Shamim Hafiz - MSFT Oct 07 '11 at 12:50
  • If you'd edit your answer to read bounds instead of x-axis I'd consider it for the answer. – Sam Oct 07 '11 at 15:16