Reputation: 33
#include <iostream>
#include <list>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
int main()
{
using Point = boost::geometry::model::d2::point_xy<double>;
using MultiPoint = boost::geometry::model::multi_point<Point>;
MultiPoint test_poly;
boost::geometry::append(test_poly, Point(2, 0));
boost::geometry::append(test_poly, Point(-2, 0));
boost::geometry::append(test_poly, Point(0, 2));
boost::geometry::append(test_poly, Point(2, 0));
std::cout << "within_result: "
<< boost::geometry::within(Point(0, 1), test_poly) << std::endl;
return 0;
}
Why the result is false, although (0,0) is obviously inside the polygon? Is it the problem caused by multipoint?
Upvotes: 2
Views: 156
Reputation: 393064
Yes. (0,0) is obviously inside the polygon.
You call the variable a test_poly
but your model isn't a polygon. Multi-points do not have any area. The only way for a point to be "within" the multipoint, is for the exact point to be in the set of points.
Compare with the below testbed:
#include <boost/core/demangle.hpp>
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
namespace bg = boost::geometry;
using Point = bg::model::d2::point_xy<double>;
using Polygon = bg::model::polygon<Point>;
using MultiPoint = bg::model::multi_point<Point>;
using MultiPoly = bg::model::multi_polygon<Polygon>;
template <typename Geometry> void buildBox(int offset, Geometry& g) {
using P = typename bg::point_type<Geometry>::type;
bg::append(g, P(offset, 0));
bg::append(g, P(-offset, 0));
bg::append(g, P(0, offset));
bg::append(g, P(offset, 0));
}
void buildBox(int offset, MultiPoly& g) { buildBox(offset, g.emplace_back()); }
template <typename Geometry> void do_test() {
Geometry g;
buildBox(2, g);
std::cout << "\n--- " << boost::core::demangle(typeid(Geometry).name())
<< " --- \n"
<< bg::wkt(g) << "\n";
if (std::string reason; not bg::is_valid(g, reason)) {
std::cout << "trying to correct: " << reason << "\n";
bg::correct(g);
std::cout << " -> (" << bg::wkt(g) << ")\n";
}
for (auto test : {Point{0, 1}, {0, 2}, {0, 3}})
std::cout << "within(" << bg::wkt(test)
<< ", g): " << bg::within(test, g) << std::endl;
}
int main() {
std::cout << std::boolalpha;
do_test<MultiPoint>();
do_test<Polygon>();
do_test<MultiPoly>();
}
Which prints
--- boost::geometry::model::multi_point<boost::geometry::model::d2::point_xy<double, boost::geometry::cs::cartesian>, std::vector, std::allocator> ---
MULTIPOINT((2 0),(-2 0),(0 2),(2 0))
within(POINT(0 1), g): false
within(POINT(0 2), g): true
--- boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double, boost::geometry::cs::cartesian>, true, true, std::vector, std::vector, std::allocator, std::allocator> ---
POLYGON((2 0,-2 0,0 2,2 0))
within(POINT(0 1), g): true
within(POINT(0 2), g): false
--- boost::geometry::model::multi_polygon<boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double, boost::geometry::cs::cartesian>, true, true, std::vector, std::vector, std::a
llocator, std::allocator>, std::vector, std::allocator> ---
MULTIPOLYGON(((2 0,-2 0,0 2,2 0)))
within(POINT(0 1), g): true
within(POINT(0 2), g): false
Upvotes: 2