Question

It seems that I have trouble in using correctly the boost geometry library ( Boost::geometry : calculation of the centroid of a polygon ). I very much appreciated the help on my previous question and would like to ask something about the boost::geometry::within method, answering if one geometry is contained in another one.

I'm using it in my code to check if a point is contained in a polygon, and I'm encountering weird results where a point should definitely not be inside a polygon far away but the method still returns True when called.

I'm thinking about a subtlety I'm missing when declaring my polygon, and I would really like to pin down this trouble. Though looking at my code back and forth, I'm lacking ideas in debugging this, and it feels like a got tunnel vision. That's why I'd like to have an hint on this specific example:

My point has coordinates: 221.703 , 256

The polygon is coordinates are, point by point:

266.158 256 266.447 256.5 267.024 256.5 267.313 257 267.024 257.5 267.313 258

which clearly shouldn't contain the point given above.

I'm sorry to ask on something this pedantic, but I'd be really thankful to anyone willing to put their nose in this

My code:

#include <iostream>
#include <boost/geometry.hpp>

using namespace std;
namespace bg = boost::geometry;
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef bg::model::polygon<point, false, true> polygon;


int main(int argc, char * argv[]){
polygon pol;
pol.outer().push_back(point(266.158,256));
pol.outer().push_back(point(266.447,256.5));
pol.outer().push_back(point(267.024,256.5));
pol.outer().push_back(point(267.313,257));
pol.outer().push_back(point(267.024,257.5));
pol.outer().push_back(point(267.313,258));

double x = atof(argv[1]);
double y = atof(argv[2]);
cout << "Is inside: " << ((bg::within(point(x,y),pol)) ? "yes" : "no") << endl;
return 0;
}
Was it helpful?

Solution

When you use bg::model::polygon<point, false, true> you are defining a polygon that uses point as its point type, that has its points in counter clockwise order and that is closed (meaning that its last point is equal to its first). If you either "close" your polygon or use an open polygon, the behaviour of bg::within seems to be what you expect:

Running on Coliru

#include <iostream>
#include <boost/geometry.hpp>

using std::cout;
using std::endl;
namespace bg = boost::geometry;
typedef bg::model::point<float, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
typedef bg::model::polygon<point, false, true> closed_polygon;
typedef bg::model::polygon<point, false, false> open_polygon;



int main(int argc, char * argv[])
{
    {
        closed_polygon pol;
        pol.outer().push_back(point(266.158,256));
        pol.outer().push_back(point(266.447,256.5));
        pol.outer().push_back(point(267.024,256.5));
        pol.outer().push_back(point(267.313,257));
        pol.outer().push_back(point(267.024,257.5));
        pol.outer().push_back(point(267.313,258));
        pol.outer().push_back(point(266.158,256));//you need to close the polygon

        double x = 222;
        double y = 257;
        cout << "Is " << bg::wkt<point>(point(x,y)) << " inside: " << ((bg::within(point(x,y),pol)) ? "yes" : "no") << endl;

        x = 267;
        y = 257;
        cout << "Is " << bg::wkt<point>(point(x,y)) << " inside: " << ((bg::within(point(x,y),pol)) ? "yes" : "no") << endl;
    }

    {
        open_polygon pol;
        pol.outer().push_back(point(266.158,256));
        pol.outer().push_back(point(266.447,256.5));
        pol.outer().push_back(point(267.024,256.5));
        pol.outer().push_back(point(267.313,257));
        pol.outer().push_back(point(267.024,257.5));
        pol.outer().push_back(point(267.313,258));

        double x = 222;
        double y = 257;
        cout << "Is " << bg::wkt<point>(point(x,y)) << " inside: " << ((bg::within(point(x,y),pol)) ? "yes" : "no") << endl;

        x = 267;
        y = 257;
        cout << "Is " << bg::wkt<point>(point(x,y)) << " inside: " << ((bg::within(point(x,y),pol)) ? "yes" : "no") << endl;
    }

    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top