jzepeda
jzepeda

Reputation: 1610

Using boost::geometry::difference, why am I getting an empty result when using multi_polygon and not with a regular polygon?

Given the following code:

typedef boost::geometry::model::d2::point_xy<int16_t, boost::geometry::cs::cartesian> Point_t;
typedef boost::geometry::model::polygon<Point_t> Polygon_t;
typedef boost::geometry::model::multi_polygon<Polygon_t> MultiPolygon_t;

std::vector<Point_t> points1;
points1.push_back(Point_t(1473, 627));
points1.push_back(Point_t(1473, 1155));
points1.push_back(Point_t(908, 1155));
points1.push_back(Point_t(908, 627));

Polygon_t poly1;
boost::geometry::assign_points(poly1, points1);
boost::geometry::correct(poly1);

MultiPolygon_t multiPoly;

multiPoly.push_back(poly1);

std::vector<Point_t> points2;
points2.push_back(Point_t(1956, 956));
points2.push_back(Point_t(1956, 1028));
points2.push_back(Point_t(115, 1023));
points2.push_back(Point_t(127, 951));

Polygon_t poly2;
boost::geometry::assign_points(poly2, points2);
boost::geometry::correct(poly2);

MultiPolygon_t resultMulti;
MultiPolygon_t resultSimple;

boost::geometry::difference(multiPoly, poly2, resultMulti);
boost::geometry::difference(poly1, poly2, resultSimple);

bool bMultiEmpty = resultMulti.empty();
bool bSimpleEmpty = resultSimple.empty();

EAGLE_ASSERT(!bSimpleEmpty);
EAGLE_ASSERT(!bMultiEmpty);

I get the results:

bSimpleEmpty -> FALSE
bMultiEmpty -> TRUE

I would expect the result to be non-empty in both cases... the only thing in the multipolygon is the same polygon is use for the bSimpleEmpty calculation. Have I fallen to a misconception?

Using Boost 1.51

Please advise!

Upvotes: 1

Views: 403

Answers (2)

jzepeda
jzepeda

Reputation: 1610

It looks like the problem is an overflow in the boost libraries when using 16 bit ints as the template parameter for coordinate types. It seems to work perfectly when using doubles.

Upvotes: 1

sehe
sehe

Reputation: 392911

I get no "disconnect". Are you sure you're using the same code? If so, see if upgrading Boost helps:

Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <iostream>
#include <vector>

typedef boost::geometry::model::d2::point_xy<int16_t, boost::geometry::cs::cartesian> Point_t;
typedef boost::geometry::model::polygon<Point_t> Polygon_t;
typedef boost::geometry::model::multi_polygon<Polygon_t> MultiPolygon_t;

int main() {

    Polygon_t poly1;
    {
        std::vector<Point_t> points1;
        points1.push_back(Point_t(1473, 627));
        points1.push_back(Point_t(1473, 1155));
        points1.push_back(Point_t(908,  1155));
        points1.push_back(Point_t(908,  627));

        boost::geometry::assign_points(poly1, points1);
        boost::geometry::correct(poly1);
    }

    Polygon_t poly2;
    {
        std::vector<Point_t> points2;
        points2.push_back(Point_t(1956, 956));
        points2.push_back(Point_t(1956, 1028));
        points2.push_back(Point_t(115,  1023));
        points2.push_back(Point_t(127,  951));

        boost::geometry::assign_points(poly2, points2);
        boost::geometry::correct(poly2);
    }

    //////////////////////////////////
    //
    MultiPolygon_t multiPoly;
    multiPoly.push_back(poly1);

    MultiPolygon_t resultMulti;
    MultiPolygon_t resultSimple;

    boost::geometry::difference(multiPoly, poly2, resultMulti);
    boost::geometry::difference(poly1,     poly2, resultSimple);

    bool bMultiEmpty  = resultMulti.empty();
    bool bSimpleEmpty = resultSimple.empty();

    std::cout << std::boolalpha << bSimpleEmpty << ", " << bMultiEmpty << "\n";
}

Prints

true, true

Upvotes: 0

Related Questions