C++ 带boost的多边形相交

C++ 带boost的多边形相交,c++,boost,polygon,boost-geometry,boost-polygon,C++,Boost,Polygon,Boost Geometry,Boost Polygon,我正在尝试使用Boost多边形库使两个多边形相交。我从boost网站提出的自定义_多边形示例开始: 在test_polygon函数中,我填充了两个多边形。我的问题是,是否可以用poly1和poly2调用交集函数。如果我编译,我有一个很长的错误列表 #include <boost/polygon/polygon.hpp> #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_x

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

在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;
}
#包括
#包括
#包括
#包括
//我的重点课程
类MyPoint{
公众:
双x,y;
};
//MyPolygon作为MyPoint的列表
typedef std::list MyPolygon;
模板
结构增强::多边形::几何体概念{
类型定义点\概念类型;
};
模板
结构增强::多边形::点特征{
typedef双坐标_型;
静态内联坐标类型get(常量MyPoint&point,boost::polygon::orientation\u 2d orient){
如果(方向==推进::多边形::水平)
返回点x;
返回点y;
}
};
模板
结构增强::多边形::点可变特征{
typedef双坐标_型;
静态内联无效集(MyPoint和point,boost::polygon::orientation\u 2d orient,双值){
如果(方向==推进::多边形::水平)
点x=值;
其他的
点y=值;
}
静态内联MyPoint构造(双x_值,双y_值){
MyPoint retval;
retval.x=x_值;
retval.y=y_值;
返回返回;
}
};
模板
结构增强::多边形::几何体概念{
typedef boost::polygon::polygon_概念类型;
};
模板
结构增强::多边形::多边形特征{
typedef双坐标_型;
typedef MyPolygon::const_iterator iterator_type;
typedef MyPoint_type;
静态内联迭代器类型开始点(const MyPolygon&t){
返回t.begin();
}
静态内联迭代器类型端点(const MyPolygon&t){
返回t.end();
}
//获取多边形的边数
静态内联std::size\u t size(const MyPolygon&t){
返回t.size();
}
//获取多边形的缠绕方向
静态直列绕组\u方向绕组(常数MyPolygon&t){
回程线圈;
}
};
模板
结构增强::多边形::多边形可变特征{
//需要stl风格的迭代器
模板
静态内联MyPolygon和set_点(MyPolygon&t、iT输入_开始、iT输入_结束){
t、 清除();
t、 插入(t.end(),输入开始,输入结束);
返回t;
}
};
模板
无效测试_多边形(){
多边形poly1,poly2;
//定义向量容器
std::vector::point_type>vpoints;
vpoints.push_back(boost::polygon::construct(0.0,0.0));
vpoints.push_back(boost::polygon::construct(0.0,1.0));
push_back(boost::polygon::construct(1.0,1.0));
push_back(boost::polygon::construct(1.0,0.0));
vpoints.push_back(boost::polygon::construct(0.05,0.0));
boost::polygon::set_points(poly1,vpoints.begin(),vpoints.end());
vpoints.clear();
push_back(boost::polygon::construct(0.5,-0.5));
push_back(boost::polygon::construct(0.5,0.5));
vpoints.push_back(boost::polygon::construct(1.5,0.5));
push_back(boost::polygon::construct(1.5,-0.5));
push_back(boost::polygon::construct(0.5,-0.5));
boost::polygon::set_points(poly2,vpoints.begin(),vpoints.end());
std::deque输出;
几何体:交集(poly1,poly2,输出);//错误!!!
}
int main(){
测试多边形();
系统(“暂停”);
返回0;
}

您似乎混淆了两个boost库

以下是使用just 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";
}
笔记 我用
vector
替换了
list
,因为*REGISTER\u LINESTRING宏需要随机访问迭代器。如果你真的能帮上忙的话,你可以走“复杂”的路线,那就是
std::list
,但这可能会使算法效率低下:


您正在使用的特性用于增强多边形。这是另一个比boost geometry更棒的库。非常感谢!!!现在我明白了我的错误,代码做了我想做的。对我来说,从列表到向量的转换没有问题。嗨,我检查了算法,多边形之间的交点是可以的。我还有一个问题,也可以得到这种结构的相交多边形吗?这就是你得到的。除此之外,它是一个多多边形,因为两个形状的一般交集可能是多个(不相交)多边形如果我使用BOOST_GEOMETRY_REGISTER_RING(std::vector)而不是BOOST_GEOMETRY_REGISTER_LINESTRING(MyPolygon),我将获得交集的点polygon@Bruce与示例无关,“它取决于”多边形模型。但是,该库有一些通用访问器:
Intersection: LINESTRING(1 0.5,1 0.5)
Intersection: LINESTRING(0.5 0,0.5 0)