【问题标题】:Identify outer border of bordering polygons C++识别边界多边形的外边界 C++
【发布时间】:2020-05-26 03:35:24
【问题描述】:

我正在寻找有关我一直在努力解决的算法的建议。我有一些用代码表示的东西(稍后显示),如下图所示(左侧为初始状态,右侧为所需输出):

我用 C++ 表示如下:

#include <vector>

using namespace std;

class Shape {

    public:
        Shape(vector<vector<float> > c) {
            coordinates = c;
        }

        vector<vector<float> > coordinates; // in format {{x1,y1},{x2,y2}}
};

class Shape_Group {
    public:
        Shape_Group(vector<Shape> s) {
            shapes = s;
        }

        vector<Shape> shapes;
        Shape generate_border();
};

Shape Shape_Group::generate_border() {
    /* 
        define algorithm here
    */
}

int main() {
    // define rectangle shapes
    Shape s1({{0,0}, {0,1}, {1,1}, {1,0}});
    Shape s2({{0,0}, {0,1}, {1,-1}, {-1,0}});

    Shape_Group group({s1, s2}); 
    Shape border = group.generate_border(); // should return a shape with the exterior border
    // border should be filed with {{1,0}, {1,1}, {1,-1}, {-1,0}};
}

我最初生成这个外部形状的想法是做如下的事情:

loop through each line segment for each shape in the Shape_Group object
    loop through every other segment in the Shape_Group object
        if both line segments are colinear and overlap, remove them

whatever's left over should be the exterior border

但是,对于大量输入,这是一个非常慢的算法。我还能做什么?

【问题讨论】:

  • 您的输入形状可以重叠吗? (可以存在两个形状内的点?)生成的形状中是否有孔? (多个形状形成字母 O 的外环,但没有形状覆盖中心?)是否有多​​个不连接的形状“岛”,这样您就可以有效地寻找两个输出形状,而不仅仅是一?对输入有任何保证,还是纯粹的任意形状?
  • 唯一的保证是输入的形状不重叠。是的,可以有形状的“岛屿”,也可以在最终的形状中存在孔。
  • 那么首先,当然,你需要一个数据结构来表示生成的 Shape 实际上表示两个形状这一事实。现在它只是一个点列表,没有指示从哪里开始,另一个在哪里结束。此外,您提出的算法仅在有额外保证的情况下才有效 - 任何边界形状都需要共享相同的确切边缘(一个较小的形状,其短段接触较大形状的一部分,中间较长的边缘,例如,会破坏它)。这也有保证吗?
  • 不,这不能保证,但这不会破坏提议的算法。这些线仍然是共线的和重叠的(重叠意味着多于一个点被线共享)。你说这个数据结构需要修改是正确的——一个三维向量可以解决这个问题。我可以编辑问题。
  • 是的,它会破坏它。想象一个轴对齐的正方形 (x1=0, y1=0, x2=3, y2=3) 和另一个轴对齐的正方形 (x1=1, y1=3, x2=2, y2=4)。如果较大正方形的边 (0,3) -> (3,3) 仅由两个点表示,您会检测到它与较小正方形的边 (1,3) -> (2,3) 重叠正方形并将它们都删除,留下一个“开放”的形状。

标签: c++ algorithm geometry


【解决方案1】:

几何O(n^2)方法:

  1. 列出所有边

  2. 删除所有内部边缘

    使用hit test 检测内部/外部边缘。

  3. 将所有剩余边重新连接到新的多边形中

    只需连接共享同一端点的边。

如果你想要更简单的东西,那么O(n) 图形方法:

  1. 渲染你的形状
  2. 用特定颜色填充背景
  3. 删除所有不相邻背景颜色的边缘

这有点相关:

它还结合了矢量图形和像素访问...

也有不同的方法来解决这个问题,例如这个:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    相关资源
    最近更新 更多