Reputation: 8277
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;
}
Upvotes: 2
Views: 1635
Reputation: 155
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:
#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;
}
Upvotes: 3