Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 是否有一种简单的方法来检测线段交点?_Php_Geometry - Fatal编程技术网

Php 是否有一种简单的方法来检测线段交点?

Php 是否有一种简单的方法来检测线段交点?,php,geometry,Php,Geometry,这比一开始看起来要复杂得多。我拥有的是一个巨大的数组,它由更多包含点的数组组成[以数组“x,y”的形式],如下所示: Array ( [0] => Array ( [0] => "0,9", [1] => "0,0", [2] => "9,0", [3] => "9,9", [4] => "0,9" ) [1] => Array (

这比一开始看起来要复杂得多。我拥有的是一个巨大的数组,它由更多包含点的数组组成[以数组“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”,而该数组中没有其他点。阵列中的最后一个点不会循环回阵列中的第一个点。此外,如果一条线段在另一条线段的交点处结束,则不应将其视为交点,它实际上需要与它相交的线段相交

我正在考虑在处理这些片段时绘制它们。比如说,通过阵列,在“虚拟”网格上绘制每个点,然后每个阵列将计算它是否与已绘制的另一段相交(如果有意义的话),但这似乎仍然需要一段时间来计算阵列中是否有大量线段。看起来我要做的是对数组中的每个段,计算它是否与之前的任何段相交(因为理论上它可以与它所在的相同数组中的段相交)。必须有一个更简单的方法来做到这一点,对吗


另外,除了PHP,我真的想不出这个应该属于什么标签。如果您有任何想法,请随时重新标记。

这里有一个简单的方法,如果每个列表中的点数较少,则可以接受:

  • 取阵列中的前两条线段,然后单击
  • 如果没有,请对照前一条线段检查下一条线段
  • 继续到最后一点,并对另一个数组重复(我假设您正在对每个子数组执行此检查)
  • 这是O(n2),其中n是所有子数组中的点数——如果n很小——太棒了,如果不是,请告诉我们

    更新:如果O(n2)不够好。。。 -假定为O(n对数(n))

    输入:平面中的一组线段


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

    这相当简单。首先计算每条线的方程式(斜率和Y截距)。斜率为(Y1-Y2)/(X1-X2)。Y截距为Y1-斜率*X1。然后我们可以用Y=mX+b的形式表示这条线,其中m=斜率,b=Y截距

    一旦你计算了一对直线的交叉点,你就可以计算出这些直线的交叉点。这是其中一条直线的X和Y坐标等于另一条直线的X和Y坐标。换句话说,其中一条直线的方程等于另一条直线的方程:m1X+b1=m2X+b2。然后可以通过隔离X来求解该方程。例如,给定两条线Y=3x+5和Y=0.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值是否都在X1和X2之间


    如果你要检查很多线的交叉点,你可能会想查找“平面扫描算法”(我不会尝试包含链接,但通过谷歌搜索应该会有相当多的点击量)。

    几乎是重复的。您需要对数据进行一些预处理,以将其转换为一组线的形式,但关于交点的其他一切都是从这里开始的:它是同一个点数组中的线的交点(例如
    $points[1]
    ),还是仅在数组之间(
    $points[0]
    $points[1]
    相交)或者两者都有?两者都有,我试图找到所有子数组中所有线段的交点。每个子数组仅仅是一个“相关”段的集合,这些段彼此相连,所以说它们是分组在一起的?因此,不是每个线段都有两个点,而是这些线段使用前一个点作为原点,当前点作为终点,这有意义吗?我将研究扫描线算法。我并不是说每一组线段都会形成一个多边形,有些线段只是形成随机的线,并以随机的方向旋转。第一组线段恰好形成一个正方形。我刚才说的是,单个子数组中的线段有可能相互相交,所以它们也需要检查。对,如果它循环的话,它们会形成一个多边形。另外,扫描线算法的定义解释了你的问题。我发现这个链接似乎可以更好地解释这个问题。当两个端点的x值相同时,任何使用坡度的方法都注定会失败。有很多解决方案不使用slope。@Phkahler:这并不是注定要失败的——这是一个特例,但很难处理。