【问题标题】:Geometric difference of regions with internal boundaries with boost geometry具有内部边界的区域的几何差异与增强几何
【发布时间】:2019-03-07 14:08:22
【问题描述】:

我想用 Boost Geometry 计算两个几何对象的几何差异。第一个几何是:

我总是有线段构成几何。我有坐标和线段:

{{-1., -1.}, {1., -1.}, {1., 1.}, {-1., 1.}, {0.6, -1}, {0.6,1.}};
{Line[{{1, 5}, {5, 2}, {2, 3}, {3, 6}, {6, 4}, {4, 1}}], Line[{{5, 6}}]};

行中的每个索引都指的是一个坐标。任何一个几何图形都可以有内部边界(和孔)。

第二个几何:

我希望得到这个:

我从 polygon 开始,但我不明白如何包含第一个几何对象的内部边界。虽然可以有内部孔,但我想念如何拥有像线一样的“退化”多边形。我也不清楚这两个多边形中的哪一个是外多边形。然后我想到了line,但是我不能添加内部段。 Boost Geometry 可以用于查找具有内部边界的几何的几何布尔运算吗?那么,我该怎么做?

错过内部边界的多边形方法的代码;注释掉的是线型方法;再次在第一个几何对象中没有内部边界。

#include <iostream>                                                             
#include <fstream>                                                              
#include <list>                                                                 

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

#include <boost/foreach.hpp>                                                    

int main()                                                                      
{                                                                               
    typedef boost::geometry::model::d2::point_xy<double> point_type;            
    typedef boost::geometry::model::polygon<point_type > polygon;               
    //typedef boost::geometry::model::linestring<point_type > line;             

    polygon p1, p2;                                                             
    //line l1, l2;                                                              

    boost::geometry::read_wkt(                                                  
        "POLYGON((-1 -1, 0.6 -1, 1 -1, 1 1, 0.6 1, -1 1))", p1);                

    boost::geometry::read_wkt(                                                  
        "POLYGON((-0.5 -0.5, 2 -0.5, 2 0.5, -0.5 0.5))", p2);                   

    /*                                                                          
    boost::geometry::read_wkt(                                                  
        "LINESTRING(-1 -1, 0.6 -1, 1 -1, 1 1, 0.6 1, -1 1)", l1);               

    boost::geometry::read_wkt(                                                  
        "LINESTRING(-0.5 -0.5, 2 -0.5, 2 0.5, -0.5 0.5)", l2);                  
    */                                                                          

    std::list<polygon> output;                                                  
    boost::geometry::difference(p2, p1, output);                                

    //std::list<line> loutput;                                                  
    //boost::geometry::difference(l2, l1, loutput);                             

    std::ofstream svg("my_map.svg");                                            
    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400);              

    int i = 0;                                                                  
    BOOST_FOREACH(polygon const& p, output)                                     
    {                                                                           
        mapper.add(p);                                                          
        mapper.map(p, "fill-opacity:0.3;fill:rgb(51,151,53);stroke:rgb(51,151,53);stroke-width:2");  
    }                                                                           

    /*                                                                          
    int i = 0;                                                                  
    BOOST_FOREACH(line const& l, loutput)                                       
    {                                                                           
        mapper.add(l);                                                          
        mapper.map(l, "opacity:0.4;fill:none;stroke:rgb(212,0,0);stroke-width:5");
    }                                                                           
    */                                                                          

    return 0;                                                                   
}

【问题讨论】:

  • 您可以尝试将第一个几何图形分成两个相互接触的矩形。那么内部线实际上是两个重合的边。或者您可以尝试将内部线建模为进入矩形的尖峰,例如从底部到顶部并立即返回(退化的向内凹痕),即POLYGON((-1 -1, 0.6 -1, 0.6 1, 0.6 -1, 1 -1, 1 1, -1 1))

标签: boost geometry boost-geometry


【解决方案1】:

内线可以建模为尖峰,例如底部。这个近似值有效:

boost::geometry::read_wkt(
    "POLYGON((-1 -1, 0.6 -1, 0.6 1, 0.60000000000001 -1, 1 -1, 1 1, -1 1))", p1);

创建了两个多边形:右下角几乎是矩形的小(0.60000000000001 -1, 1 -1, 1 -0.5, 0.6 -0.5) 未与其余多边形相连。

这个确切的点列表

boost::geometry::read_wkt(
    "POLYGON((-1 -1, 0.6 -1, 0.6 1, 0.6 -1, 1 -1, 1 1, -1 1))", p1);

由于自交集而引发异常。当跳过检查自相交时,我们得到一个结果,但它是不完整的(仅计算上述两个多边形中较大的一个)。

当然,也可以将多边形 p1 分成两个矩形:

boost::geometry::read_wkt(
    "POLYGON((-1 -1, 0.6 -1, 0.6 1, -1 1))", p11);
boost::geometry::read_wkt(
    "POLYGON((0.6 -1, 1 -1, 1 1, 0.6 1))", p12);

然后使用p2 计算每个差异并将结果连接起来给出准确的预期答案(作为三个单独的矩形)。

【讨论】:

  • 感谢您的回答和您的宝贵时间。你的第二个建议是更可行的。但是,然后,我必须找到一种方法将我拥有的原始线段表示(参见问题更新)转换为多边形列表。我没有立即看到如何做到这一点,实际上这样做非常困难。从您的回答中,我相信提升可能不是我想做的正确工具。我将把这个打开一段时间,看看其他人是否能想出一个办法来做到这一点。再次感谢!
  • 你的规范还不清楚:你总是有像{polygon, lines}这样的输入吗?单线是否只出现在第一个几何图形中?如果单线也可以出现在第二个几何图形中,您必须定义在这种情况下的差异意味着什么?计算差异时是否应忽略第二个几何图形中的单线?无论如何,输出可以是{polygons, lines} 的形式。唯一缺少的就是计算line - polygon的算法。
  • 任一几何体都可以有内部段(和孔),并且几何体由线段组成。 RegionDifference(p1, p2) 表示从 p1 中减去所有 p2(包括内部边界)。由于 p2 不会成为差异结果的一部分,因此无需担心。对于区域漏洞,这是一个不同的故事,但不是问题的一部分。非常感谢您的帮助,但我得出的结论是 boost 几何不会为我削减它。
猜你喜欢
  • 2018-08-08
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2021-06-08
  • 2014-10-12
  • 1970-01-01
相关资源
最近更新 更多