计算立方体之间的距离(如果存在环绕效果)

时间:2018-09-17 20:09:50

标签: javascript algorithm

我有一个由较小的立方体组成的大立方体。大立方体由10个宽,10个长,10个高的立方体组成。一共1000个立方体。

  • 一个立方体将被随机选择为蓝色
  • 三个立方体将被随机选择为绿色

我希望能够确定最接近蓝色立方体的绿色立方体。

重要的另一件事是立方体的每一侧都连接到另一侧(即,认为第10行紧挨着第1行)。这是环绕效果。

例如,如果蓝色立方体位于坐标9:8:8,绿色立方体分别位于1:2:2、5:5:3和6:3:4。然后,应将1:2:2处的绿色立方体视为最近的立方体。如果我的计算正确,则距离应为10,而其他两个距离应为12。

没有立方体的环绕(第1面与第10面相连),我已经能够在JavaScript中提出以下内容:

let lowest = 1000;
let lowest_index = -1;

for (i = 0; i < green_cube.length; i++){

    let x_offset = Math.abs(blue_cube.x - green_cube[i].x);
    let y_offset = Math.abs(blue_cube.y - green_cube[i].y);
    let z_offset = Math.abs(blue_cube.z - green_cube[i].z);

    let distance = x_offset + y_offset + z_offset;
    if (distance < lowest){
        lowest = distance;
        lowest_index = i;
    }
}

使环绕效果生效时,正确的编码方式是什么?

更新

为清楚起见,该距离必须是从点A到点B所经过的立方数的距离。必须仅沿X,Y和Z轴移动距离,因此,对角线距离将不起作用。我相信这被称为3D空间中的出租车距离。

5 个答案:

答案 0 :(得分:1)

我相信它通常被称为环绕式。

要综合考虑您的距离度量,例如x维度应为:

let x_offset = Math.min((10 + blue.x - green[i].x) % 10, (10 + green[i].x - blue.x) % 10)

x_offset将始终为正。

答案 1 :(得分:0)

这是一个愚蠢的把戏,可以使您保持思路清晰。

v为向量(5, 5, 5) - blue_cube。将v添加到每个多维数据集的位置,如果超出边缘则添加/减去10。现在,蓝色立方体位于(5, 5, 5)处,而通往其他立方体的最短路径不再越过边界。

在您的示例中,v = (5, 5, 5) - (9, 8, 8) = (-4, -3, -3)。第一个绿色立方体移动到(1, 2, 2) + (-4, -3, -3) = (-3, -1, -1) = (7, 9, 9),距离为10。第二个绿色立方体移动到(5, 5, 3) + (-4, -3, -3) = (1, 2, 0),距离为12。第三个绿色立方体移动到(6, 3, 4) + (-4, -3, -3) = (2, 0, 1),距离再次为12.所以第一个确实是最接近的。

答案 2 :(得分:0)

在这段代码中,我对3d(reference)中的2个点使用距离计算公式。

enter image description here

const calculateDistance3d = ({x: x1, y: y1, z: z1}, {x: x2, y: y2, z: z2}) => {
  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2));
}

const calculateLoopedDistance = (cubeA, cubeB) => {
  return calculateDistance3d(cubeA, {
    x: cubeA.x + 10 - Math.abs(cubeB.x - cubeA.x),
    y: cubeA.y + 10 - Math.abs(cubeB.y - cubeA.y), 
    z: cubeA.z + 10 - Math.abs(cubeB.z - cubeA.z)
  });  
};

const getClosest = (green_cube, blue_cube) => {
  let minDistance = 1000; 
  let closestIndex = 0;
  
  blue_cube.forEach((cube, index) => {
    const distance = calculateDistance3d(green_cube, cube);
    const loopedDistance = calculateLoopedDistance(green_cube, cube);
    if (distance < minDistance || loopedDistance < minDistance) {
      minDistance = Math.min(distance, loopedDistance);
      closestIndex = index;
    }
  });
  return closestIndex;
}

console.log(getClosest({x: 9, y: 8, z: 8}, [
  {x: 1, y: 2, z: 2},
  {x: 5, y: 5, z: 3},
  {x: 6, y: 3, z: 4}
]));

console.log(getClosest({x: 9, y: 8, z: 8}, [
  {x: 5, y: 5, z: 3},
  {x: 1, y: 2, z: 2},
  {x: 6, y: 3, z: 4}
]));

在此脚本的末尾,有2个包含多维数据集数据的日志。您可以在那里测试不同的数据。

我更新/修复了calculateLoopedDistance() 功能,该功能不正确。

答案 3 :(得分:0)

Virtually replicate the green cubes as if they appeared at x, x-10 and x+10 and keep the minimum delta. This is done on the three axis independently.

答案 4 :(得分:0)

我遇到了另一个可行的解决方案:

let cube_width = 10;
let mid_point = cube_width / 2;

let x_offset = Math.abs(point1 - point2);
if (x_offset > mid_point){
    x_offset = cube_width - x_offset;
}

我很难确定此解决方案或SirRaffleBuffle的解决方案在时间上是否更有效。