使用 boost 将几何体切割成碎片

Posted

技术标签:

【中文标题】使用 boost 将几何体切割成碎片【英文标题】:Cutting geometries into pieces using boost 【发布时间】:2018-07-19 11:28:25 【问题描述】:

boost::geometry 中是否有任何内置工具可以切割如下图所示的几何图形?我的想法是找到一个相交几何,并从两个来源中减去它们。但是,当有超过 2 个相交的矩形共享相同的区域时,这感觉不是最好的解决方案。

因此,将输入数据转换为代码中的同构测试用例:

Live On Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/io/io.hpp>
#include <iostream>
#include <fstream>

namespace bg  = boost::geometry;
namespace bgm = bg::model;

using point = bgm::d2::point_xy<int>;
using poly  = bgm::polygon<point>;
using mpoly = bgm::multi_polygon<poly>;

int main()

    poly a, b, c;
    bg::read_wkt("POLYGON((0 0 0 6 6 6 6 0 0 0))", a);
    bg::read_wkt("POLYGON((4 -1 4 4 5 4 5 -1 4 -1))", b);
    bg::read_wkt("POLYGON((3 -3 3 3 9 3 9 -3 3 -3))", c);

    std::cout << bg::wkt(a) << "\n";
    std::cout << bg::wkt(b) << "\n";
    std::cout << bg::wkt(c) << "\n";

    
        std::ofstream svg("output.svg");
        boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
        mapper.add(a);
        mapper.add(b);
        mapper.add(c);

        mapper.map(a, "fill-opacity:0.2;fill:rgb(0,0,153);stroke:rgb(0,0,200);stroke-width:2");
        mapper.map(b, "fill-opacity:0.2;fill:rgb(153,0,0);stroke:rgb(200,0,0);stroke-width:2");
        mapper.map(c, "fill-opacity:0.2;fill:rgb(0,153,0);stroke:rgb(0,200,0);stroke-width:2");
    

这反映了以下 SVG:

【问题讨论】:

您有与您“担心”的案例相符的样本吗?我不清楚未描述的“共享同一区域”究竟是什么意思 @sehe,更新描述 看到了,添加了一些代码让它更直观。 【参考方案1】:

考虑以下代码:

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

#include <boost/foreach.hpp>
#include <boost/foreach.hpp>


namespace bg  = boost::geometry;
namespace bgm = bg::model;

typedef  bgm::d2::point_xy<int> point;
typedef  bgm::polygon<point> poly;
typedef  bgm::multi_polygon<poly> mpoly;

int main()

    poly a, b, c;
    bg::read_wkt("POLYGON((0 0 0 6 6 6 6 0 0 0))", a);
    bg::read_wkt("POLYGON((4 -1 4 4 5 4 5 -1 4 -1))", b);
    bg::read_wkt("POLYGON((3 -3 3 3 9 3 9 -3 3 -3))", c);

    std::vector<poly> polies;
    polies.push_back(a);
    polies.push_back(b);
    polies.push_back(c);

        std::vector<poly> res;
        for (size_t i = 0; i < polies.size(); ++i)
        
            for (size_t j = i; j < polies.size(); ++j)
            
                boost::geometry::model::multi_polygon<poly> output;
                boost::geometry::union_(polies[i], polies[j], output);

                for (auto it = output.begin(); it != output.end(); ++it)
                
                    res.push_back(*it);
                    
            
        

        for (size_t i = 0; i < polies.size(); ++i)
        
            for (size_t j = i; j < polies.size(); ++j)
            
                boost::geometry::model::multi_polygon<poly> multi;
                boost::geometry::sym_difference(polies[i], polies[j], multi);

                for (auto it = multi.begin(); it != multi.end(); ++it)
                
                    res.push_back(*it);
                
            
        


    
        std::ofstream svg("output2.svg");
        boost::geometry::svg_mapper<point> mapper(svg, 400, 400);
        size_t i = 0;
        BOOST_FOREACH(poly& p, res)
        
            std::stringstream ss;
            ss << ++i * 10;
            std::stringstream ss2;
            ss2 << 255 - i * 10;
            mapper.add(p);
            mapper.map(p, "fill-opacity:0.2;fill:rgb("+ ss.str() + "," + ss2.str() +",153);stroke:rgb(0,0,200);stroke-width:2");
        
    

    return 0;

产生以下输出: 为此,您必须遍历所有组合并计算初始多边形的并集和 sym_differences。

对不起,颜色不如你的好。

这有帮助吗?

【讨论】:

@sehe 我不能接受 OP 知道该功能的问题。在仅链接答案的映射器上:我应该复制内容吗?我什至不确定这是否合法。 SO的正确方法是什么?如果答案不符合 SO 方法,我也可以删除它。不知道 @sehe 你介意给我一些关于这个答案编辑的反馈吗?你以前的帖子帮助很大。谢谢。 差不多。结果向量中有几个额外的交叉多边形。正如您在第二张图片中看到的那样,它应该是 7 个多边形。使用这个解决方案,我得到了 9。无论如何,谢谢,我会努力从这一点开始 @user1496491你是对的。对不起。我更改了代码以产生所需的输出。可以查一下吗?

以上是关于使用 boost 将几何体切割成碎片的主要内容,如果未能解决你的问题,请参考以下文章

利用IO流把单个文件切割成碎片文件

如何从文件中读取行并将其切割成碎片?

外部碎片进程描述符内部碎片

如何以编程方式将图像裁剪成碎片

将图像裁剪成碎片然后加入,这可能使用 OpenCV 吗?

将随机森林分类分解成python中的碎片?