我有一个由较小的立方体组成的大立方体。大立方体由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空间中的出租车距离。
答案 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个点使用距离计算公式。
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的解决方案在时间上是否更有效。