1

First, I mean boost::polygon library, not boost::geometry library. My code is:

namespace gtl = boost::polygon;
using namespace boost::polygon::operators;
typedef gtl::polygon_90_data<int> Polygon;
typedef gtl::polygon_traits<Polygon>::point_type Point;
typedef gtl::polygon_90_set_data<int> PolygonSet;
Point pts1[] = { Point(10000, 20000), Point(12000, 20000), Point(12000, 14000), Point(10000, 14000)};
Polygon poly1;
gtl::set_points(poly1, pts1, pts1 + 4);

Point pts2[] = { Point(11500, 18000), Point(11500, 25000), Point(14000, 25000), Point(14000, 18000)};
Polygon poly2;
gtl::set_points(poly2, pts2, pts2 + 4);

PolygonSet polyset;
assign(polyset, poly1 + poly2);

I want to use the union of poly1 and poly2, it will be a polygon with 8 points. Now I have to convert the result polyset to Polygon type, but I did not find a way to do this. Anyone can tell me how can I do this?

genpfault
  • 51,148
  • 11
  • 85
  • 139
kyleqian
  • 311
  • 1
  • 3
  • 14
  • gtl::contains function can not be called with polygon_set_data and point, I must use a polygon_data and point, so I have to convert a polygon_set_data which is union of 2 polygon_data to polygon_data. – kyleqian Jan 14 '18 at 14:39
  • Wow. You basically changed the question completely, in a comment. I'm keeping the answer as I don't think there's really a more straightforwad answer to the underlying goal, but maybe someone else would know (I'd use Boost Geometry for this task) – sehe Jan 14 '18 at 15:08

1 Answers1

1

The union of two polygons isn't strictly always a single polygon (what if they were disjunct to begin with).

If you know this to be the case, I'd suggest just getting the first polygon of the set (perhaps asserting that the set has size 1).

std::vector<Polygon> v;
polyset.get_polygons(v);
if (v.size() == 1) {
    std::cout << "Union was: ";
    Polygon p = std::move(v.front()); // attempt to prevent copying
    for (auto& pt : p)
        std::cout << "{" << pt.x() << ", " << pt.y() << "} ";
} else {
    std::cout << "Something not quite right here\n";
}

See it Live On Coliru printing

Union was: {140, 180} {120, 180} {120, 140} {100, 140} {100, 200} {115, 200} {115, 250} {140, 250} 

BONUS

I'd probably write it more like:

Live On Coliru

#include <boost/polygon/point_traits.hpp>
#include <boost/polygon/polygon.hpp>
#include <boost/polygon/polygon_set_data.hpp>
#include <boost/polygon/polygon_set_traits.hpp>
#include <boost/polygon/polygon_traits.hpp>

namespace gtl = boost::polygon;
using namespace boost::polygon::operators;

typedef gtl::polygon_90_data<int> Polygon;
typedef gtl::polygon_traits<Polygon>::point_type Point;
typedef gtl::polygon_90_set_data<int> PolygonSet;

Polygon make_polygon(std::initializer_list<Point> init) {
    Polygon p;
    p.set(init.begin(), init.end());
    return p;
}

template <typename P>
P get_union(P const& a, P const& b) {
    std::vector<P> v;
    PolygonSet(a+b).get(v);
    assert(v.size() == 1);
    return std::move(v.front());
}

int main() {
    Polygon u = get_union(
       make_polygon({ {100, 200}, {120, 200}, {120, 140}, {100, 140} }),
       make_polygon({ {115, 180}, {115, 250}, {140, 250}, {140, 180} }));

    for (auto& pt : u)
        std::cout << "{" << pt.x() << ", " << pt.y() << "} ";
}

Printing the same

sehe
  • 374,641
  • 47
  • 450
  • 633