Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Construct polygons out of union of many polygons

Supposed that I have many polygons, what is the best algorithm to construct a polygon--maybe with holes- out of the union of all those polygons?

For my purpose, you can imagine each piece of a polygon as a jigsaw puzzle piece, when you complete them you will get a nice picture. But the catch is that a small portion ( say <5%) of the jigsaw is missing, and you are still require to form a picture as complete as possible; that's the polygon ( or polygons)-- maybe with holes-- that I want to form.

My naive approach is to take two polygons, union them, and take another polygon, union it with the union of the two polygons, and repeat this process until every single piece is union. Then I will run through the union polygon list and check whether there are still some polygons can be combined, and I will repeat this process until a satisfactory result is achieved.

But this seems to be like an extremely naive approach. I just wonder is there any other better algorithm?

like image 737
Graviton Avatar asked Dec 24 '10 11:12

Graviton


2 Answers

You need a polygon clipping library - and I'll plug my own Clipper library since it's written in C# (and C++ and Delphi), it's open source freeware, and it'll do exactly what you want.

My naive approach is to take two polygons, union them, and take another polygon, union it with the union of the two polygons, and repeat this process until every single piece is union

That would be a very inefficient approach. A much better way would be to 'union' them all in one operation ...

using ClipperLib;
using Polygon = List<IntPoint>;
using Polygons = List<List<IntPoint>>;
...

//precondition: all your polygons have the same orientation 
//(ie either clockwise or counter clockwise)
Polygons polys = new Polygons(PolyCnt);
for (int i = 0; i < PolyCnt; i++)
    polys.Add(loadPolyFromFile(String.Format("poly{0}.txt", i +1)));

Polygons solution = new Polygons();
Clipper c = new Clipper();
c.AddPolygons(polys, PolyType.ptSubject);
c.Execute(ClipType.ctUnion, solution, 
    PolyFillType.pftNonZero, PolyFillType.pftNonZero);

//code to display solution here.
like image 94
Angus Johnson Avatar answered Nov 01 '22 10:11

Angus Johnson


That's brute force what's your doing. A better way of doing brute force is branch and bound. But that still scales horribly.

The next step is to try metaheuristic algorithms (tabu search, simulated annealing, ...) or just reuse a framework like Drools Planner (open source, java) which implements them for you.

like image 43
Geoffrey De Smet Avatar answered Nov 01 '22 09:11

Geoffrey De Smet