【问题标题】:topology layers separation algorithm拓扑层分离算法
【发布时间】:2012-02-01 18:57:34
【问题描述】:

我有以下问题。假设您在平面上有大量曼哈顿多边形(它们的边平行于 x 或 y 轴)。我需要找到一个多边形,放置得比某个值增量更近。问题是如何以最有效的方式做到这一点,因为这个多边形的数量非常大。如果您能给我参考已实施的解决方案,我会很高兴,这将很容易适应我的情况。

【问题讨论】:

  • 多边形可以凹吗?自相交?它们有孔吗?
  • 您要查找什么确切信息?两点之间的最近距离比delta短的多边形对?或者您应该找到至少参与其中一对的所有多边形?
  • 多边形可以是凹的,但不能自相交。它们不包含孔。参与至少一对这样的多边形。抱歉不确定

标签: c++ polygon


【解决方案1】:

首先想到的是sweep and prune算法(也称为sort and sweep)。

基本上,您首先要找出每个形状沿每个轴的“边界”。对于 x 轴,这些将是形状上最左边和最右边的点。对于 y 轴,最高和最低。

假设您有一个看起来像这样的绑定结构:

struct Bound
{
    float value;      // The value of the bound, ie, the x or y coordinate.
    bool  isLower;    // True for a lower bound (leftmost point or bottommost point).
    int   shapeIndex; // The index (into your array of shapes) of the shape this bound is on.
};

为这些 Bounds 创建两个数组,一个用于 x 轴,一个用于 y 轴。

Bound xBounds* = new Bound[2 * numberOfShapes];
Bound yBounds* = new Bound[2 * numberOfShapes];

您还需要另外两个数组。一个数组,用于跟踪每对形状在多少个轴上彼此接近,以及一个候选对数组。

int closeAxes* = new int[numberOfShapes * numberOfShapes];

for (int i = 0; i < numberOfShapes * numberOfShapes; i++)
    CloseAxes[i] = 0;

struct Pair
{
    int shapeIndexA;
    int shapeIndexB;
};

Pair candidatePairs* = new Pair[numberOfShapes * numberOfShape];
int numberOfPairs = 0;

遍历您的形状列表并适当地填充数组,但有一个警告: 由于您正在检查接近度而不是相交,因此将 delta 添加到每个上限。 然后使用您喜欢的任何算法按值对每个数组进行排序。

接下来,执行以下操作(并对 Y 轴重复):

for (int i = 0; i + 1 < 2 * numberOfShapes; i++)
{
    if (xBounds[i].isLower && xBounds[i + 1].isLower)
    {
        unsigned int L = xBounds[i].shapeIndex;
        unsigned int R = xBounds[i + 1].shapeIndex;

        closeAxes[L + R * numberOfShapes]++;
        closeAxes[R + L * numberOfShapes]++;

        if (closeAxes[L + R * numberOfShapes] == 2 ||
            closeAxes[R + L * numberOfShapes] == 2)
        {
            candidatePairs[numberOfPairs].shapeIndexA = L;
            candidatePairs[numberOfPairs].shapeIndexB = R;
            numberOfPairs++;
        }
    }
}

所有候选对在每个轴上的距离都小于 delta。现在只需检查每个候选对以确保它们实际上小于 delta。我现在不会详细说明如何做到这一点,因为,好吧,我还没有真正考虑过,但希望我的回答至少能让你开始。我想您可以只检查每对线段并找到最短的 x 或 y 距离,但我确信有一种更有效的方法来执行“窄相”步骤。

显然,该算法的实际实现可能要复杂得多。我的目标是使解释清晰而简短,而不是优雅。根据形状的布局和使用的排序算法,就效率而言,单次运行大约在 O(n) 和 O(n log n) 之间,而不是 O(n^2) 来检查每个一对形状。

【讨论】:

    猜你喜欢
    • 2020-07-01
    • 2023-03-16
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多