c++ - 带 boost 的多边形相交

标签 c++ boost polygon boost-geometry boost-polygon

我正在尝试使用 Boost Polygon 库使两个多边形相交。我从 boost 网站提出的 custom_polygon 示例开始:

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;
}

最佳答案

您似乎混淆了两个 boost 库。

这是仅使用 boost 几何体的快速调整:

Live On Coliru

#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,那么您可以走“复杂”路线,但这可能会使算法效率低下:

关于c++ - 带 boost 的多边形相交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32651234/

相关文章:

c++ - OpenGL中的顺时针和逆时针

c++ - libboost 1.62 错误选项 --log_sink

polygon - 从纬度/经度多边形获取边界框

c++ - 使用堆栈确定表达式是否具有平衡括号

c++ - 为什么boost::condition_variable可以使用pthread_cond_signal来仅唤醒一个线程

c++ - boost::thread & 成员函数

c++ - 如何为 x86 和 x64 架构构建 boost 通用库?

c++ - 为什么这个 ASIO 示例使用成员变量来传递状态而不是使用绑定(bind)?

c - 用于对多边形轮廓中的顶点进行排序的线性时间算法

R使用沿边界保留单元格的多边形裁剪栅格