Пересечение полигонов с бустом

Я пытаюсь пересечь два полигона с помощью библиотеки Boost Polygon. Я начал с примера custom_polygon, предложенного на веб-сайте boost:

http://www.boost.org/doc/libs/1_59_0/libs/polygon/doc/gtl_custom_polygon.htm

В функции test_polygon я заполняю два полигона. У меня вопрос, возможно ли вызвать функцию пересечения с poly1 и poly2. Если я скомпилирую, у меня будет очень длинный список ошибок.

#include <boost/polygon/polygon.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

#include <list>// My Point class
class MyPoint {
public:
double x, y;
};

// MyPolygon as a list of MyPoint
typedef std::list<MyPoint> MyPolygon;template <>
struct boost::polygon::geometry_concept<MyPoint> {
typedef point_concept type;
};

template <>
struct boost::polygon::point_traits<MyPoint> {

typedef double coordinate_type;

static inline coordinate_type get(const MyPoint& point, boost::polygon::orientation_2d orient) {
if (orient == boost::polygon::HORIZONTAL)
return point.x;
return point.y;
}
};template <>
struct boost::polygon::point_mutable_traits<MyPoint> {

typedef double coordinate_type;

static inline void set(MyPoint& point, boost::polygon::orientation_2d orient, double value) {
if (orient == boost::polygon::HORIZONTAL)
point.x = value;
else
point.y = value;
}

static inline MyPoint construct(double x_value, double y_value) {
MyPoint retval;
retval.x = x_value;
retval.y = y_value;
return retval;
}
};template <>
struct  boost::polygon::geometry_concept<MyPolygon>{
typedef  boost::polygon::polygon_concept type;
};template <>
struct  boost::polygon::polygon_traits<MyPolygon> {

typedef double coordinate_type;

typedef MyPolygon::const_iterator iterator_type;

typedef MyPoint point_type;

static inline iterator_type begin_points(const MyPolygon& t) {
return t.begin();
}
static inline iterator_type end_points(const MyPolygon& t) {
return t.end();
}

// Get the number of sides of the polygon
static inline std::size_t size(const MyPolygon& t) {
return t.size();
}

// Get the winding direction of the polygon
static inline winding_direction winding(const MyPolygon& t) {
return unknown_winding;
}
};template <>
struct  boost::polygon::polygon_mutable_traits<MyPolygon> {

//expects stl style iterators
template < typename iT >
static inline MyPolygon& set_points(MyPolygon& t, iT input_begin, iT input_end) {
t.clear();
t.insert(t.end(), input_begin, input_end);
return t;
}
};template < typename Polygon, typename Point >
void test_polygon() {

Polygon poly1, poly2;

// Define a vector container
std::vector< boost::polygon::polygon_traits< Polygon >::point_type  > vpoints;

vpoints.push_back(boost::polygon::construct<Point>(0.0, 0.0));
vpoints.push_back(boost::polygon::construct<Point>(0.0, 1.0));
vpoints.push_back(boost::polygon::construct<Point>(1.0, 1.0));
vpoints.push_back(boost::polygon::construct<Point>(1.0, 0.0));
vpoints.push_back(boost::polygon::construct<Point>(0.05, 0.0));
boost::polygon::set_points(poly1, vpoints.begin(), vpoints.end());
vpoints.clear();

vpoints.push_back(boost::polygon::construct<Point>(0.5, -0.5));
vpoints.push_back(boost::polygon::construct<Point>(0.5, 0.5));
vpoints.push_back(boost::polygon::construct<Point>(1.5, 0.5));
vpoints.push_back(boost::polygon::construct<Point>(1.5, -0.5));
vpoints.push_back(boost::polygon::construct<Point>(0.5, -0.5));
boost::polygon::set_points(poly2, vpoints.begin(), vpoints.end());

std::deque<Polygon> output;
boost::geometry::intersection(poly1, poly2, output);  // ERROR!!!

}int main() {
test_polygon< MyPolygon, MyPoint >();
system("pause");
return 0;
}

2

Решение

Вы, кажется, путаете две библиотеки повышения.

Вот быстрая адаптация с использованием только Boost Geometry:

Жить на Колиру

#include <boost/geometry.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/linestring.hpp>

namespace bg = boost::geometry;

struct MyPoint {
double x, y;
};

typedef std::vector<MyPoint> MyPolygon;

BOOST_GEOMETRY_REGISTER_POINT_2D(MyPoint, double, bg::cs::cartesian, x, y)
BOOST_GEOMETRY_REGISTER_LINESTRING(MyPolygon)

template < typename Polygon, typename Point >
std::deque<Polygon> test_polygon() {

Polygon poly1 { {0.0,  0.0}, {0.0, 1.0}, {1.0, 1.0}, {1.0,  0.0}, {0.05,  0.0}, };
Polygon poly2 { {0.5, -0.5}, {0.5, 0.5}, {1.5, 0.5}, {1.5, -0.5},  {0.5, -0.5}, };

std::deque<Polygon> output;
boost::geometry::intersection(poly1, poly2, output);

return output;
}

int main() {
for (auto& p : test_polygon< MyPolygon, MyPoint >())
std::cout << "Intersection: " << bg::wkt(p) << "\n";
}

Печать:

Intersection: LINESTRING(1 0.5,1 0.5)
Intersection: LINESTRING(0.5 0,0.5 0)

Заметки

Я заменил list с vector потому что макрос * REGISTER_LINESTRING требует итераторов произвольного доступа. Вы можете пойти по «сложному» маршруту, если вы действительно может помочь std::list, но это, вероятно, сделает алгоритмы неэффективными:

3

Другие решения


По вопросам рекламы [email protected]