Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.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
Javascript 查找最近的三维点_Javascript_Node.js_Math_Nearest Neighbor - Fatal编程技术网

Javascript 查找最近的三维点

Javascript 查找最近的三维点,javascript,node.js,math,nearest-neighbor,Javascript,Node.js,Math,Nearest Neighbor,假设我有一个播放器位于:X:100,Y:100,Z:100,我想找到以下哪一点最接近并获得它的ID: ID: 1, X: 200; Y: 200; Z: 100, ID: 2, X: 150; Y: 300; Z: 300, ID: 3, X: 300; Y: 200; Z: 100, ID: 4, X: 50; Y: 100; Z: 200 我怎么做呢?它背后的数学原理是什么?如果有帮助,我已经有以下代码: var returnVehicles = []; mp.vehicl

假设我有一个播放器位于:
X:100,Y:100,Z:100
,我想找到以下哪一点最接近并获得它的ID:

ID: 1, X: 200; Y: 200; Z: 100,
ID: 2, X: 150; Y: 300; Z: 300,
ID: 3, X: 300; Y: 200; Z: 100,
ID: 4, X: 50; Y: 100; Z: 200
我怎么做呢?它背后的数学原理是什么?如果有帮助,我已经有以下代码:

var returnVehicles = [];
        mp.vehicles.forEachInRange(player.position, 100, (vehicle) => {
                if(vehicle.ownerID == player.id) {
                    returnVehicles.push(vehicle.position, vehicle.id);
                }
            }
        );
它在100的范围内循环通过车辆,并将属于玩家的车辆的ID和位置添加到一个数组中。然而,我不知道该怎么办

有人向我推荐.sort()方法,但这似乎不起作用,因为它只获取最小的坐标,而不是最近的坐标

@编辑:我的完整代码

function distance3D(posA, posB) {
    const dX = posA.X - posB.X;
    const dY = posA.Y - posB.Y;
    const dZ = posA.Z - posB.Z;
    return Math.sqrt(dX * dX + dY * dY + dZ * dZ);
}

const vehiclesAndDistances = [];

function lockPlayerVehicle (player) {
    let vehicle = player.vehicle;
    if (vehicle) {
        //IRRELEVANT
    }
    else {
        mp.vehicles.forEachInRange(player.position, 40, (vehicle) => {
                if(vehicle.ownerID == player.id) {
                    vehiclesAndDistances.push({vehicle, distance: distance3D(player, vehicle),});
                }
            }
        );
        vehiclesAndDistances.sort((a, b) => a.distance - b.distance);
        player.outputChatBox("Lista Pequena: " + String(vehiclesAndDistances[0]));
        console.log(vehiclesAndDistances[0], vehiclesAndDistances[0].vehicle.model)
    };
}
mp.events.add("keypress:DOWNARROW", lockPlayerVehicle);

对于少量车辆,只需使用查找车辆与玩家之间的距离就足够了。(对于少数情况(或者如果需要经常循环),您可能需要研究空间分区算法,如四叉树,以使查找更有效。)

编辑:如评论中所述,如果您只需要最近的点,可以将其重新表述为

let closestDistance = undefined;
let closestVehicle = undefined;

mp.vehicles.forEachInRange(player.position, 100, (vehicle) => {
  if (vehicle.ownerID === player.id) {
    const distance = distance3D(player, vehicle);
    if (closestDistance === undefined || distance < closestDistance) {
      closestVehicle = vehicle;
      closestDistance = distance;
    }
  }
});
let closestDistance=未定义;
let closestVehicle=未定义;
mp.vehicles.ForEachRange(玩家位置,100,(车辆)=>{
如果(vehicle.ownerID==玩家id){
常量距离=距离3D(玩家、车辆);
if(最近距离===未定义的| |距离<最近距离){
关闭车辆=车辆;
最近距离=距离;
}
}
});

对于少量车辆,只需使用查找车辆与播放器之间的距离就足够了。(对于少数情况(或者如果需要经常循环),您可能需要研究空间分区算法,如四叉树,以使查找更有效。)

编辑:如评论中所述,如果您只需要最近的点,可以将其重新表述为

let closestDistance = undefined;
let closestVehicle = undefined;

mp.vehicles.forEachInRange(player.position, 100, (vehicle) => {
  if (vehicle.ownerID === player.id) {
    const distance = distance3D(player, vehicle);
    if (closestDistance === undefined || distance < closestDistance) {
      closestVehicle = vehicle;
      closestDistance = distance;
    }
  }
});
let closestDistance=未定义;
let closestVehicle=未定义;
mp.vehicles.ForEachRange(玩家位置,100,(车辆)=>{
如果(vehicle.ownerID==玩家id){
常量距离=距离3D(玩家、车辆);
if(最近距离===未定义的| |距离<最近距离){
关闭车辆=车辆;
最近距离=距离;
}
}
});
您可以使用。将其应用于每个点并选择最小值。时间复杂度是线性的,但您可能在每帧的循环中运行它,因此总体复杂度是二次的。有可用的优化。看

不改变时间复杂度的可能微观优化包括避免平方根操作、一次保存最小值等

const dist=(a,b)=>Math.sqrt(
(b.X-a.X)**2+
(b.Y-a.Y)**2+
(b.Z-a.Z)**2
);
常数最近=(目标点,eps=0.00001)=>{
常量距离=点.map(e=>dist(target,e));
常数最近=数学最小值(…距离);
返回点。查找((e,i)=>距离[i]-最近的您可以使用。将其应用于每个点并选择最小值。时间复杂度是线性的,但您可能在每帧的循环中运行它,因此总体复杂度是二次的。有可用的优化。看

不改变时间复杂度的可能微观优化包括避免平方根操作、一次保存最小值等

const dist=(a,b)=>Math.sqrt(
(b.X-a.X)**2+
(b.Y-a.Y)**2+
(b.Z-a.Z)**2
);
常数最近=(目标点,eps=0.00001)=>{
常量距离=点.map(e=>dist(target,e));
常数最近=数学最小值(…距离);
返回点。查找((e,i)=>距离[i]-最近的日志(最近的(玩家,点数))您可以使用欧几里德距离计算公式。将所有坐标放在一个数组中,并使用map创建一个新的距离数组,该距离数组是通过实现欧几里德公式导出的。可以按升序或降序对数组中的元素进行排序,并找到距离

let currData=[{
ID:1,
X:200,
Y:200,
Z:100
},
{
ID:2,
X:150,
Y:300,
Z:300
},
{
ID:3,
X:300,
Y:200,
Z:100
},
{
ID:4,
X:50,
Y:100,
Z:200
}
]
常数vehlPos={
X:250,
Y:400,
Z:600
};
让getDist=currData.map((项)=>{
const xdiff=Math.pow((vehlPos.X-item.X),2);
const ydiff=数学功率((vehlPos.Y-item.Y),2);
常数zdiff=数学功率((vehlPos.Z-项目Z),2);
返回Math.sqrt(xdiff+ydiff+zdiff)
});

console.log(getDist)
您可以使用欧几里德距离计算公式。将所有坐标放在一个数组中,并使用map创建一个新的距离数组,该距离数组是通过实现欧几里德公式导出的。可以按升序或降序对数组中的元素进行排序,并找到距离

let currData=[{
ID:1,
X:200,
Y:200,
Z:100
},
{
ID:2,
X:150,
Y:300,
Z:300
},
{
ID:3,
X:300,
Y:200,
Z:100
},
{
ID:4,
X:50,
Y:100,
Z:200
}
]
常数vehlPos={
X:250,
Y:400,
Z:600
};
让getDist=currData.map((项)=>{
const xdiff=Math.pow((vehlPos.X-item.X),2);
const ydiff=数学功率((vehlPos.Y-item.Y),2);
常数zdiff=数学功率((vehlPos.Z-项目Z),2);
返回Math.sqrt(xdiff+ydiff+zdiff)
});

log(getDist)
您可以将对象转换为点并使用向量函数

下面是一个3D向量类的示例