Php 用距离法查找/计算笛卡尔平面上最近的对象

Php 用距离法查找/计算笛卡尔平面上最近的对象,php,Php,所以我尝试用PHP创建一个脚本,在笛卡尔平面(xy)上有多个对象,并找到最近的距离 例如,假设在XY平面上有3个对象,我想通过距离找到最近的2个对象 现在我可以使用距离公式: 但是,如何在此基础上编写一个接受对象数组的函数 我的想法是这样的(请告知): -数组$objects将是(包含名称/坐标的对象的)列表 -它应该返回最接近的数组对象名称 $object1 = ['object1' => 'a', 'x' => 1, 'y' => 1]; $object2 = ['obj

所以我尝试用PHP创建一个脚本,在笛卡尔平面(xy)上有多个对象,并找到最近的距离

例如,假设在XY平面上有3个对象,我想通过距离找到最近的2个对象

现在我可以使用距离公式:

但是,如何在此基础上编写一个接受对象数组的函数

我的想法是这样的(请告知):

-数组$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))

}
  • 将对象放入数组中
  • 迭代数组
  • 不执行
    sqrt()
    可以节省相当多的CPU周期,因为您不关心文字距离是多少
  • 例如:

    函数getDistanceIsh($a,$b){ 返回功率(绝对值($a['x']-$b['x']),2)+功率(绝对值($a['y']-$b['y']),2); } $testPoint=['x'=>1,'y'=>2]; $closest=$objects[0]; $closestDist=getDistance($testpoint,$objects[0]);
    对于($i=1,$c=count($objects);$i对于3个对象,只有2个对象的3种组合—1+2、1+3和2+3

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

    function distance($obj1,$obj2) {
      return sqrt(pow(($obj1['x']-$obj2['x']),2) + pow(($obj1['y']-$obj2['y']),2));
    }
    
    现在计算两个对象的每个组合,并将结果存储在数组中:

    $dist['12'] = distance($object1,$object2) ;
    $dist['13'] = distance($object1,$object3) ;
    $dist['23'] = distance($object2,$object3) ;
    
    // sort values into ascending order
    asort($dist);
    // take 1st element index
    reset($dist);
    $closest = key($dist);
    
    echo $closest;
    

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

    为计算成本如此高的程序编写自己的代码实际上是一个糟糕的开始。始终首先尝试看看是否有任何开源代码可以更快地执行相同的任务,并且re way。因为这些代码经过许多专业人士的验证,大部分都是无错误的,而且还可以减少开发时间。因此,在您的情况下,首先找到最快的算法是很重要的。它被广泛用于寻找最短路径,一些开源PHP代码示例是和e对象数量(当然需要超过1个)。它使用,这与您的距离公式基本相同

    $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]
    ];
    函数findClosestObjects(数组$objects){
    //将$minDistance初始化为null
    $minDistance=null;
    //对象总数
    $len=计数($objects);
    //从第一个对象到第二个对象再到最后一个对象的循环
    //最后一个将在嵌套for循环中处理
    对于($i=0;$i<$len-1;$i++){
    //将$o1设置为当前$i对象
    $o1=$objects[$i];
    //从下一个对象循环到最后一个对象,以避免重复对
    对于($j=$i+1;$j<$len;$j++){
    //将$o2设置为当前$j对象
    $o2=$objects[$j];
    //计算距离
    $distance=hypot($o2['x']-$o1['x'],$o2['y']-$o1['y']);
    //如果$minDistance为空或$distance小于$minDistance
    如果($minDistance==null | |$minDistance>$distance){
    //将对象和距离放入$result中
    $result=[$o1,$o2,'distance'=>$distance];
    //并更新$minDistance
    $minDistance=$distance;
    }
    }
    }
    返回$result;
    }
    var_dump(findClosestObjects($objects));
    

    我认为@prim3的意思是在一组对象中找到最接近的两个对象,而不是根据探测点进行测试。但我可能错了。我有一个大脑的东西,我要在这里转储:对于大量的点,你可以:1.创建空间索引。2.取第一个点并计算距离。3.查询内部点的索引e该半径,如果找到,则设置较小的半径,然后继续所有其他点。4.具有
    O(n*log(n))
    或类似的复杂性。
    $dist['12'] = distance($object1,$object2) ;
    $dist['13'] = distance($object1,$object3) ;
    $dist['23'] = distance($object2,$object3) ;
    
    // sort values into ascending order
    asort($dist);
    // take 1st element index
    reset($dist);
    $closest = key($dist);
    
    echo $closest;