【问题标题】:PHP Find Coordinates between two pointsPHP查找两点之间的坐标
【发布时间】:2010-03-14 06:09:32
【问题描述】:

这里有一个简单的问题。假设我有两点:

point 1

x = 0
y = 0


point 2

x = 10
y = 10

假设两点之间有一条海峡,我如何以编程方式找出所有坐标之间的坐标...所以上面的示例将返回:

0,0
1,1
2,2
3,3
...
8,8
9,9
10,10

谢谢:)

【问题讨论】:

  • 不要吹毛求疵,但平面上任意两点之间的点数是无限的。如果您的意思是积分点,那就不同了,但是您的最小步长将决定有多少最大点。
  • 我建议你用一个更好的例子,因为这使得直线方程 y=x 这不是通常的情况。

标签: php math loops coordinates


【解决方案1】:

你需要先找到直线的斜率:

m = (y1 - y2) / (x1 - x2)

那么你需要找到直线的方程:

y = mx + b

在您的示例中,我们得到:

y = 1x + b
0 = 1(0) + b

y = x

要获得所有坐标,您只需插入所有值 x1 -> x2。在 PHP 中,这整个事情看起来像:

// These are in the form array(x_cord, y_cord)
$pt1 = array(0, 0);
$pt2 = array(10, 10);
$m = ($pt1[1] - $pt2[1]) / ($pt1[0] - $pt2[0]);
$b = $pt1[1] - $m * $pt1[0];

for ($i = $pt1[0]; $i <= $pt2[0]; $i++)
    $points[] = array($i, $m * $i + $b);

这当然会为您提供落在 X 整数值上的所有点的坐标,而不是两点之间的“所有坐标”。

【讨论】:

  • +1,您的代码似乎完全符合我最初希望我的代码做的事情,它更干净,看起来更像是一个可靠的解决方案。
  • 你打败了我。无论如何,我把我的算法留给那些想要的人。
  • 测试垂直线留给用户作为练习。
【解决方案2】:

感谢您的所有帮助,但发布的答案均未达到我想要的效果。例如,假设我的观点是:

0, 0

0, 10

只会有一个开始和一个结束坐标......它不会找到介于两者之间的坐标。

也许我做错了什么:S,但我想出了自己的解决方案:

// Points
$p1 = array(
    'x' => 50,
    'y' => 50
);

$p2 = array(
    'x' => 234,
    'y' => 177
);

// Work out distances
$pxd = $p2['x'] - $p1['x'];
$pyd = $p2['y'] - $p1['y'];

// Find out steps
$steps = max($p1['x'], $p1['y'], $p2['x'], $p2['y']);

$coords = array();

for ($i = 0; $i < $steps; ++ $i) {
    $coords[] = array(
        'x' => round($p1['x'] += $pxd / $steps),
        'y' => round($p1['y'] += $pyd / $steps)
    );
}

print_r($coords);

【讨论】:

  • 您发现了解决方案 y = a + bx 不起作用的两个例外之一。原因是斜率 b 将是无限的(因为没有定义除以 0,并且 x1 - x2 为 0)。但是,您的解决方案有缺点:您只计算右上象限的离散值(正 x 和 y)。步数由最大坐标任意定义:取(20,0)和(21,1):有21步,而(0,5)和(1,3)只有3步。尝试改用 $steps = max($pdx, $pdy)。
  • 对 $steps 的更改工作不一致。插入 3,3 和 0,5,代码只返回两个点:2,4 和 0,5。它错过了沿 x=1 且 y=4 或 y=5 的中间点,我想这两者都是可以接受的。
【解决方案3】:
  1. 使用直线方程,y = mx + c
  2. 将 (0,0) 和 (10,10) 放入两个方程,然后求解得到 m 和 c 的值。 (您将能够找到直接方程以在某处获得 m 和 c)。
  3. 然后创建一个循环,从 x = x1 (0) 开始,直到 x = x2 (10)
  4. 使用 y=mx+c,获取 y 的值(现在您知道了 m 和 c)

【讨论】:

    【解决方案4】:

    在 (x1,y1) 和 (x2,y2) 之间的线段上生成所有格点(具有整数坐标的点),其中 x1、x2、y1 和 y2 为整数:

    function gcd($a,$b) {
        // implement the Euclidean algorithm for finding the greatest common divisor of two integers, always returning a non-negative value
        $a = abs($a);
        $b = abs($b);
        if ($a == 0) {
            return $b;
        } else if ($b == 0) {
            return $a;
        } else {
            return gcd(min($a,$b),max($a,$b) % min($a,$b));
        }
    }
    
    function lattice_points($x1, $y1, $x2, $y2) {
        $delta_x = $x2 - $x1;
        $delta_y = $y2 - $y1;
        $steps = gcd($delta_x, $delta_y);
        $points = array();
        for ($i = 0; $i <= $steps; $i++) {
            $x = $x1 + $i * $delta_x / $steps;
            $y = $y1 + $i * $delta_y / $steps;
            $points[] = "({$x},{$y})";
        }
        return $points;
    }
    

    【讨论】:

    • 似乎无法始终如一地工作。给定 (3,3,0,5) 它只返回 3,3 和 0,5 但没有任何中间点。与 (3,3,0,6) 一起正常工作,这是一条完美的“45 度线”,但在其他斜坡上效果不佳。
    • @DonJones:在 (3,3) 和 (0,5) 之间的线段上没有任何格点,即两个坐标都是整数的点。
    【解决方案5】:

    一个更简单的算法是,通过平均坐标找到中点,重复直到你完成。只是想指出,因为没有人指出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2014-01-16
      • 2016-05-10
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2011-05-09
      相关资源
      最近更新 更多