通过距离PHP查找/计算笛卡尔平面上最接近的对象

时间:2018-07-19 20:40:35

标签: php

因此,我试图在PHP中创建一个在笛卡尔平面(xy)上具有多个对象的脚本,并找到最接近的距离。

例如,假设我们在XY平面上有3个对象,而我想按距离查找2个最接近的对象。

现在我可以使用距离公式: http://www.mathwarehouse.com/algebra/distance_formula/index.php

但是,我如何在该函数上编写一个接收对象数组的函数?

我在想这样的事情(请告知):

-array $ objects将是(带有名称/坐标的对象的)列表。
-它应返回数组最接近的对象名称

$object1 = ['object1' => 'a', 'x' => 1, 'y' => 1];
$object2 = ['object2' => 'b', 'x' => 1, 'y' => 3];
$object3 = ['object3' => 'c', 'x' => 5, 'y' => 5];

我不确定该如何写。我已经启动了该功能:

function findClosestObject(array $objects) {

  d = sqrt(pow((x2-x1),2) + pow((y2-y1)),2))

}

4 个答案:

答案 0 :(得分:1)

  1. 将对象放入数组中。
  2. 遍历数组。
  3. 由于您不关心字面距离是多少,因此不执行sqrt()可以节省相当数量的CPU周期。

例如:

function getDistanceIsh($a, $b) {
    return pow(abs(($a['x']-$b['x'])), 2) + pow(abs(($a['y']-$b['y'])), 2);
}

$testPoint = ['x'=>1, 'y'=>2];
$closest = $objects[0];
$closestDist = getDistance($testpoint, $objects[0]);

for( $i=1,$c=count($objects); $i<$c; $i++ ) {
    $dist = getDistance($testpoint, $objects[$i]);
    if( $dist < $closestDist ) {
        $closest = $objects[$i];
        $closestDist = $dist;
    }
}

答案 1 :(得分:1)

对于3个对象,只有2个对象的3种组合-1 + 2、1 + 3和2 + 3。

将距离公式抽象为一个函数:

non-root user within my container

现在计算两个对象的每种组合,并将结果存储在数组中:

function distance($obj1,$obj2) {
  return sqrt(pow(($obj1['x']-$obj2['x']),2) + pow(($obj1['y']-$obj2['y']),2));
}

要对更大的对象数组执行此操作,您将需要实现首先生成所有两个对象组合的代码。

答案 2 :(得分:0)

为这样的计算昂贵的程序编写自己的代码实际上是一个糟糕的开始。始终总是首先尝试看看是否有任何开源代码可以更快,更安全地执行同一任务。因为这些代码已经过许多专业人员的验证,并且大多数情况下都不会出现错误,因此也减少了您的开发时间。因此,在您的情况下,首先找到最快的算法很重要。 Dijkstra Algorithm被广泛用于查找最短路径,并且一些开放源代码PHP代码的示例是PHP-DijkstraTaniko-Dijkstra

答案 3 :(得分:0)

这是一个解决方案,允许对象数量可变(当然需要超过1个)。它使用hypot(),与您的距离公式基本相同。

$objects = [
  [ 'name' => 'obj1', 'x' => 1,  'y' => 1 ],
  [ 'name' => 'obj2', 'x' => 1,  'y' => 3 ],
  [ 'name' => 'obj3', 'x' => 5,  'y' => 5 ],
  [ 'name' => 'obj4', 'x' => 10, 'y' => 8 ],
  [ 'name' => 'obj5', 'x' => 30, 'y' => 12 ],
  [ 'name' => 'obj6', 'x' => 31, 'y' => 13 ],
  [ 'name' => 'obj7', 'x' => 40, 'y' => 15 ]
];

function findClosestObjects( array $objects ) {
  // initialize $minDistance to null
  $minDistance = null;
  // total amount of objects
  $len = count( $objects );

  // loop from first object to the second-to-last
  // last will be handled inside nested for loop
  for( $i = 0; $i < $len - 1; $i++ ) {
    // set $o1 to current $i object
    $o1 = $objects[ $i ];
    // loop from next object to the last, to avoid duplicate pairs
    for( $j = $i + 1; $j < $len; $j++ ) {
      // set $o2 to current $j object
      $o2 = $objects[ $j ];
      // calc distance
      $distance = hypot( $o2[ 'x' ] - $o1[ 'x' ], $o2[ 'y' ] - $o1[ 'y' ] );
      // if $minDistance is null or $distance is smaller than $minDistance
      if( $minDistance == null || $minDistance > $distance ) {
        // put objects and distance in $result
        $result = [ $o1, $o2, 'distance' => $distance ];
        // and update $minDistance
        $minDistance = $distance;
      }
    }
  }

  return $result;
}

var_dump( findClosestObjects( $objects ) );

view parsed online @ eval.in