【问题标题】:Determine if point is inside boost::geometry::linear_ring accounting orientation确定点是否在 boost::geometry::linear_ring 会计方向内
【发布时间】:2013-11-16 01:00:48
【问题描述】:

我想用boost::geometry 确定点是否在多边形内。

我使用函数boost::geometry::within 并输入boost::geometry::linear_ring<boost::geometry::point_2d> 来指定轮廓。

如果我不需要考虑轮廓的方向,一切都可以正常工作。
但就我而言,我想说明方向。我的意思是,如果特定轮廓的内部区域被认为受其边界限制并且是有限的,那么倒置轮廓的内部区域应该是无限的 - 与初始轮廓的区域互补。

是否可以在within 函数中考虑轮廓的方向?

可以用以下代码表示:

// Create contour which defines square
boost::geometry::linear_ring<boost::geometry::point_2d> contour;
contour.push_back(boost::geometry::point_2d(4, 2));
contour.push_back(boost::geometry::point_2d(2, 2));
contour.push_back(boost::geometry::point_2d(2, 4));
contour.push_back(boost::geometry::point_2d(4, 4));
contour.push_back(boost::geometry::point_2d(4, 2));

// Create contour which defines square with opposite direction.
boost::geometry::linear_ring<boost::geometry::point_2d> contourInverted = contour;
std::reverse(contourInverted.begin(), contourInverted.end());

// Specify point inside square
boost::geometry::point_2d testPoint(3, 3);

// Perform tests
bool ret1 = boost::geometry::within(testPoint, contour);
bool ret2 = boost::geometry::within(testPoint, contourInverted);

上面的代码执行后ret1ret2都是true。但我会ret1 != ret2

一般来说,当ret1 != ret2 用于任何testPoint 时,我需要获得功能(当点正好在边界上或多边形退化等时,我不考虑边界情况......)

我尝试将different strategies传递给boost::geometry::within,但我没有得到我需要的东西。

似乎我需要或类似的功能在boost::geometry 的某处实现,因为documetation for within 具有带孔的多边形示例。但我还没有意识到如何在我的情况下使用它。

还有一个非常简单的解决方法。我只需要编写一个代码来确定轮廓的方向。然后我只是根据轮廓方向否定或不否定 within 函数的结果。但如果boost::geometry 已经实现,我不想复制它。

【问题讨论】:

    标签: c++ boost boost-geometry


    【解决方案1】:

    AFAIK,Boost.Geometry 和 Boost.Polygon 都不适用于您定义的“无限”区域。他们确实使用带有孔的多边形,甚至是一组这样的多边形。

    您可以考虑添加一个大矩形来限制您的宇宙。然后您可以将倒置轮廓定义为此类矩形中的孔。

    顺便说一句,在许多情况下可以避免将框转换为轮廓。 Boost.Geometry 提供了一个适配器“box_view”,它允许像使用(正向)轮廓一样使用框。

    对于任意轮廓的方向,可能最简单的方法是计算其面积。另一方面,对于格式良好的环,方向在编译时是已知的,并且由元函数traits::point_order 提供,请参阅详细信息here

    【讨论】:

      【解决方案2】:

      几点说明:

      • 在 Boost.Geometry 中没有bg::linear_ring&lt;&gt;,有bg::model::ring&lt;&gt;
      • bg::model::ring&lt;&gt; 是 Boost.Geometry 中称为环的模型,它是一种面几何体,是一个没有孔的简单多边形。
      • Ring 与 OGC LinearRing 不同,它是一种面 (2d) 几何形状,并且具有方向。 OGC LinearRing 是一维的,没有方向。
      • 可以通过传递第二个模板参数在编译时设置bg::model::ring&lt;&gt; 的方向,参见this
      • area() 函数为反向区域(笛卡尔)几何返回的值是负区域(不是无限大)。但并非所有函数都适用于反向几何,因为库通常认为它们是无效的。

      在 Boost.Geometry 中,数据必须反映几何的编译时设置,在这种情况下,在编译时为环设置的方向。否则结果可能出乎意料。在您的情况下,返回相同的值。您可以调用bg::correct() 自动更正方向和闭合,然后再将几何传递给其他函数。您也可以致电bg::is_valid() 检查您的几何是否一切正常。

      因此,如果您想检查一个点是否与几何内部重叠,您可以调用within(pt, ring)。如果您想检查一个点是否在边界上或与外部重叠,那么!within(pt, ring) 应该返回您需要的内容,这当然是显而易见的。

      如果您想考虑边界,请检查一个点是否与内部或边界重叠,然后您可以使用covered_by(pt, ring)!disjoint(pt, ring)intersects(pt, ring)。显然,这种情况下的补码可能是!covered_by(pt, ring)disjoint(pt, ring)!intersects(pt, ring)

      在 Pt/Ring 的情况下,内部使用相同的代码来检查所有这些空间关系,因此调用哪一个无关紧要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-20
        • 2014-02-13
        相关资源
        最近更新 更多