如何获得多边形的左链点?

时间:2017-12-06 09:37:24

标签: c++ computational-geometry

我试图给左边的多边形链给出一组连续的点。 (注意:边缘不相交。)

enter image description here

图片1。示例多边形及其边界。

我做的是:

  1. 获取minYmaxYminX。 (结合)。
  2. 找到包含minY(或maxY)的点,然后将其保存为第一个点。
  3. 在使用minY检查点时找到maxYminX点之前保存所有点。
  4. 如果首先找到相同的Y,请将其保存为新的第一个点并从#3开始重复。
  5. 如果首先找到其他Y并且保存的点数为minX,则这就是链。否则,保存为新的第一个点并从#3开始重复。
  6. enter image description here

    图片2。点的左链。

    但是使用这些步骤可能会给某些多边形带来错误的结果,如下所示:

    enter image description here

    由于一个点是(minXmaxY),因此将返回任何一方。

    修改 根据左下角和左上角点的想法,这是我正在使用的当前代码:

    获取最小(左下角)和最大(左上角)点。

    std::vector<Coord> ret;
    size_t i = 0;
    Coord minCoord = poly[i];
    Coord maxCoord = poly[i];
    size_t minIdx = -1;
    size_t maxIdx = -1;
    size_t cnt = poly.size();
    i++;
    for (; i < cnt; i++)
    {
        Coord c = poly[i];
        if (c.y < minCoord.y)   // new bottom
        {
            minCoord = c;
            minIdx = i;
        }
        else if (c.y == minCoord.y) // same bottom
        {
            if (c.x < minCoord.x)   // left most
            {
                minCoord = c;
                minIdx = i;
            }
        }
        if (c.y > maxCoord.y)   // new top
        {
            maxCoord = c;
            maxIdx = i;
        }
        else if (c.y == maxCoord.y) // same top
        {
            if (c.x < maxCoord.x)   // left most
            {
                maxCoord = c;
                maxIdx = i;
            }
        }
    }
    

    获取连接到最大点的点。

    i = maxIdx;
    Coord mid = poly[i];
    Coord ray1 = poly[(i + cnt - 1) % cnt];
    Coord ray2 = poly[(i + 1) % cnt];
    

    获得最小角度。这将是我们将遵循的道路。

    double rad1 = Pts2Rad(mid, ray1);
    double rad2 = Pts2Rad(mid, ray2);
    int step = 1;
    if (rad1 < rad2)
        step = cnt - 1;
    

    保存积分。

    while (i != minIdx)
    {
        ret.push_back(poly[i]);
        i = (i + step) % cnt;
    }
    ret.push_back(poly[minIdx]);
    

1 个答案:

答案 0 :(得分:0)

具体来说,我假设没有顶点重复,并将“左链”定义为原始多边形循环中的顶点序列,该顶点从边界框顶部的最左侧顶点到最左侧边界框底部的顶点。 [如果顶部和底部两侧重合,这两个顶点也重合;在这种情况下,我留给你什么。]

要获得这些,您可以扫描所有顶点并保持左上角到目前为止最左下方。然后比较下一个顶点。如果在最左上方,则成为新的lef-topmost。如果在同一水平和左侧,成为新的左上角。同样,对于左下角。