在 boost 几何中创建实心多边形

Posted

技术标签:

【中文标题】在 boost 几何中创建实心多边形【英文标题】:Create solid polygon in boost geometry 【发布时间】:2017-11-15 16:17:14 【问题描述】:

我是 boost 几何的新手,我用boost::geometry::assign_points() 创建了多边形。但我只创建该多边形的外部和内部是空的。所以我尝试使用两个多边形 A、B 和 A 在 B 内测试 boost::geometry::overlaps(),结果不重叠。

那么,我该怎么做才能创建实心多边形(只知道多边形的外点和多边形的内部有效)?

【问题讨论】:

【参考方案1】:

多边形根据定义是实心的,直到减去内环。来自标准的§6.1.11.1¹:

多边形是由 1 个外部边界和 0 个或多个内部边界定义的平面表面。每个内饰 边界定义多边形中的一个洞。三角形是具有 3 个不同的非共线顶点且没有 内部边界。 ¹

重叠并不意味着你认为它意味着什么。

来自 §6.1.15.3(基于 DE-9IM 的命名空间关系谓词)

交叉 内

重叠

定义为

a.Overlaps(b) ⇔ ( dim(I(a)) = dim(I(b)) = dim(I(a) ∩ I(b)))
                 ∧ (a ∩ b ≠ a) ∧ (a ∩ b ≠ b)

包含

a.Contains(b) ⇔ b.Within(a)

相交

a.Intersects(b) ⇔ ! a.Disjoint(b) 

在您的情况下,您可能正在寻找 !disjointwithincontainsintersection

Live On Coliru

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

namespace bg = boost::geometry;

template <typename Geo> void debug(std::string name, Geo const& g) 
    std::string reason;
    std::cout << name << ": " << bg::dsv(g) << " " << bg::is_valid(g, reason) << ", '" << reason << "'\n"; 


template <typename Geo, typename F>
void both_ways(std::string name, Geo const& a, Geo const& b, F f) 
    std::cout << name << "(a, b) -> " << f(a,b) << "\n";
    std::cout << name << "(b, a) -> " << f(b,a) << "\n";


int main() 
    std::cout << std::boolalpha;

    using Pt = bg::model::d2::point_xy<int>;
    using Poly = bg::model::polygon<Pt>;
    using Multi = bg::model::multi_polygon<Poly>;

    Poly const a   0,0 ,  0,3 ,  3,3 ,  3,0 ,  0,0  ;
    Poly const b   1,1 ,  1,2 ,  2,2 ,  2,1 ,  1,1  ;

    debug("a", a);
    debug("b", b);

#define TEST(algo) both_ways(#algo, a, b, [](auto& a, auto& b)  return bg::algo(a, b); )
    TEST(overlaps);
    TEST(intersects);
    TEST(within);
    //TEST(contains); // contains(a,b) ⇔ within(b,a)
    //TEST(crosses); // not implemented for polygons
    TEST(disjoint);

    both_ways("intersection", a, b, [](auto& a, auto& b) 
        Multi c; 
        bg::intersection(a, b, c);
        return boost::lexical_cast<std::string>(bg::dsv(c));
    );

打印出来的

a: (((0, 0), (0, 3), (3, 3), (3, 0), (0, 0))) true, 'Geometry is valid'
b: (((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))) true, 'Geometry is valid'
overlaps(a, b) -> false
overlaps(b, a) -> false
intersects(a, b) -> true
intersects(b, a) -> true
within(a, b) -> false
within(b, a) -> true
disjoint(a, b) -> false
disjoint(b, a) -> false
intersection(a, b) -> ((((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))))
intersection(b, a) -> ((((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))))

¹OGC Simple Feature/通用架构

【讨论】:

ok,我结合了overlaps()和winthin(),它解决了我的问题:) @TuânNguyễnĐình 欢迎来到 SO。如果答案解决了您的问题,请务必接受(请参阅meta.stackexchange.com/questions/5234/…)

以上是关于在 boost 几何中创建实心多边形的主要内容,如果未能解决你的问题,请参考以下文章

boost几何中的环和多边形有什么区别?

多边形交叉与Boost ::几何严重的性能恶化

提高内点的几何多边形距离

提升几何:从多个点组成多边形

将几何多边形内部表示提升为 STL 列表?

提升几何相交会产生奇怪的结果