使用Boost Polygon的减法结果不正确

时间:2017-11-09 13:13:27

标签: c++ boost boost-polygon

我有以下两个输入多边形,我想要计算一个减去的多边形:

A:

StringBuilder

B:

               * (0, 8)
              / \
             /   \
            /     \
   (-3, 0) *-------* (3, 0)

因此,我想计算 (-1, 2) *-----* (1, 2) | | (-1, 1) *-----* (1, 1) ,这应该会产生一个带方形切口的三角形。使用Boost Polygon计算此值会导致带有切口的不正确的部分三角形。很难画出来;结果三角形的缺失部分由三角形A - B表示。我使用以下代码来计算减法:

(3, 0) => (0, 8) => (1, 2)

这将打印构成剪切三角形的以下后续点:

#include <boost/polygon/polygon.hpp>

namespace bp = boost::polygon;

int main()
{
  using Polygon = bp::polygon_data<int>;
  using Point = bp::point_data<int>;
  using PolygonSet = bp::polygon_set_data<int>;
  using SimplePolygons = std::vector<bp::polygon_data<int>>;

  using namespace boost::polygon::operators;

  Polygon A;
  {
    std::vector<Point> points{{-3, 0}, {3, 0}, {0, 8}};
    bp::set_points(A, points.begin(), points.end());
  }

  Polygon B;
  {
    std::vector<Point> points{{-1, 1}, {1, 1}, {1, 2}, {-1, 2}};
    bp::set_points(B, points.begin(), points.end());
  }

  PolygonSet result{A - B};

  SimplePolygons simplePolygons;
  result.get<SimplePolygons>(simplePolygons);
  for (const auto& polygon : simplePolygons)
  {
    for (const Point& p : polygon)
    {
      std::cout << '(' << std::to_string(p.x()) << ", " << std::to_string(p.y()) << ")\n";
    }
  }

  return 0;
}

因此,结果中缺少边(3, 0) (1, 2) (1, 1) (-1, 1) (-1, 2) (1, 2) (0, 8) (-3, 0) (3, 0) (1, 2) => (3, 0)。结果中缺少输入三角形的右上部分。

正确的输出可能如下所示:

(3, 0) => (0, 8)

这是Boost Polygon中的一个错误,我是不是错误地使用了库,还是我还缺少其他东西?

其他一些信息:

  • 我正在使用GCC 7.2.0,Boost 1.60.0。 Boost Polygon自那以后一直没有更新,因此升级Boost最有可能无济于事。
  • 使用(3, 0) (1, 2) (1, 1) (-1, 1) (-1, 2) (1, 2) (3, 0) (0, 8) (-3, 0) (3, 0) 而不是double参数化点类型和所有其他几何类型无法解决问题。
  • 使用轴对齐矩形计算切口例如可以正常工作。
  • 对于我的应用程序,我想使用Boost Polygon而不是Boost Geometry,因为它提供了多边形锁孔压裂支持。

1 个答案:

答案 0 :(得分:3)

回答我自己的问题......

Boost Polygon是用整数数据类型编写的。来自文档:

  

通常,数据类型应该定义std :: numeric_limits并且类似于整数。所有算法都不支持浮点坐标类型,目前通常不适合与库一起使用(http://www.boost.org/doc/libs/1_60_0/libs/polygon/doc/gtl_coordinate_concept.htm

我怀疑这是一些我不完全理解的精确问题。实际上,例如,将所有输入坐标缩放1000因子会产生正确的多边形:

(3000, 0)
(1000, 5333)
(1000, 2000)
(1000, 1000)
(-1000, 1000)
(-1000, 2000)
(1000, 2000)
(1000, 5333)
(0, 8000)
(-3000, 0)
(3000, 0)

因此,对于原始输入,锁眼压裂算法似乎意图在边缘(3, 0) -> (0, 8)上添加一个新顶点,从该顶点进入“锁孔多边形”#39;。它可以为此创建的整数网格位置上的最佳顶点位于(0, 8)。所以结果代表了一个近似值。

实际上,为算法提供类似的输入,在三角形边缘上存在一个好的候选顶点会产生正确的输出。一个这样的输入三角形将是例如(-4, 0) - (4, 0) - (0, 8)

我认为这是锁孔破裂算法的一个限制。