有没有一种简单的方法来检测线段交叉点?

时间:2010-03-09 18:47:21

标签: php geometry

这比起初看起来要复杂得多。我所拥有的是一个巨大的数组,它包含更多包含点[以数组“x,y”形式]的数组,如下所示:

Array (
    [0] => Array (
        [0] => "0,9",
        [1] => "0,0",
        [2] => "9,0",
        [3] => "9,9",
        [4] => "0,9"
        )
    [1] => Array (
        [0] => "1,5",
        [1] => "1,6",
        [2] => "3,6",
        [3] => "3,8",
        [4] => "4,8"
    )
    ... and so on ...
)

所以我需要做的是处理所有点并查看数组中的任何点,例如$points[0][1]$points[0][2],是否与数组中可能存在的任何其他线段相交。所有线段按照它们各自的阵列中的顺序连续。所以在第一个数组中,“0,9”变为“0,0”而该数组中没有其他点。数组中的最后一个点不会循环回到数组中的第一个点。此外,如果线段在另一个线段的交叉点处结束,则它不应被视为交叉点,它实际上需要穿过它相交的线段。

我正在考虑在处理它们时绘制段。因此,通过遍历数组绘制每个说明的“虚拟”网格上的每个点然后每个数组将计算它是否与已经绘制的另一个段相交,如果这有意义,但看起来仍然可能需要同时计算数组中是否有很多线段。看起来我正在做的是对于数组中的每个段,计算它是否与之前的任何段相交(因为理论上它可以与它所在的相同数组中的段相交)。必须有一种更简单的方法来做到这一点,对吗?

P.S。我真的不能想到除了PHP之外应该使用哪些标签。如果您有任何想法,请随时重新标记。

2 个答案:

答案 0 :(得分:1)

如果每个列表中的点数很小,这是一个简单的方法:

  1. 获取数组中的前两个线段check if they intersect
  2. 如果没有,请检查前一个线段的下一个线段
  3. 继续直到最后一点并重申另一个数组(我假设您正在检查每个子数组)。
  4. 这是 O(n 2 其中 n 是所有子阵列中的点数 - 如果 n 很小 - 很棒,如果没有,请告诉我们。

    更新:如果 O(n 2 不够好......

    Sweep line algorithm for segment intersection - 据说 O(n log(n))

    输入:平面中的一组线段。

    输出: S中段之间的交集点。

答案 1 :(得分:1)

这很容易。首先计算每条线的方程(斜率和Y截距)。斜率为(Y 1 -Y 2 )/(X 1 -X 2 )。 Y截距是Y 1 - 斜率* X 1 。然后我们可以用Y = mX + b的形式表示该线,其中m =斜率,b = Y截距。

一旦计算了一对线的那些,就计算那些线会交叉的位置。这是一行的X和Y坐标等于另一行的X和Y的地方。换句话说,其中一条线的等式等于另一条线的等式:m 1 X + b 1 = m 2 X + b'的子> 2 。然后,您可以通过隔离X来解决该等式。例如,给定两条线Y = 3x + 5和Y = .5x + 2:

3x+5 = .5x+2 // subtract 5 from both sides
3x = .5x - 3 // subtract .5x fro both sides
2.5x = -3    // divide by 2.5
x = -3/2.5   // reduce term
x = -1.2

现在我们已经建立了两个的交叉点,但是我们不知道这两个段是否扩展到足以包含该点。为此,我们需要检查两个线段的X值是否在X 1 和X 2 之间。

如果您要检查 lot 行的交叉点,您可能想要查找“平面扫描算法”(我不会尝试包含链接,但是谷歌搜索应该提供相当数量的点击率。