我有一个环形欧几里德地图。也就是说,表面是一个平坦的欧几里德矩形,但是当一个点移动到右边界时,它将出现在左边界(在相同的y值处),由x_new = x_old%width
给出基本上,基于以下方式绘制点:* 参见编辑
(x_new, y_new) = ( x_old % width, y_old % height)
Think Pac Man - 走出屏幕的一边会让你出现在对面的边缘。
计算两点之间最短距离的最佳方法是什么?典型的实施方案表明,地图对角处的点距离较远,实际上,实际包裹的距离非常接近。
我能想到的最好方法是计算经典Delta X和Wrapped Delta X,以及经典Delta Y和Wrapped Delta Y,并使用Sqrt(x ^ 2 + y ^ 2)距离公式中每对的较低值
但这会涉及许多检查,计算和操作 - 我认为可能没有必要。
有更好的方法吗?
修改的
当一个物体移动时,它移动到位置(x_old,y_old),通过上面的公式运行它,并存储(x_new,y_new)作为它的位置。仅添加上述公式以阐明当物体越过边界时会发生什么;实际上,每次只有一个(x,y)对存储在每个对象中。
答案 0 :(得分:11)
我能想到的最好方法是计算经典Delta X和Wrapped Delta X,以及经典Delta Y和Wrapped Delta Y,并使用Sqrt(x ^ 2 + y ^ 2)距离公式中每对的较低值
就是这样,我认为没有更快的方法。但是计算并不难;你可以做点什么
dx = abs(x1 - x2);
if (dx > width/2)
dx = width - dx;
// again with x -> y and width -> height
(我相信你可以将其翻译成您的首选语言)
答案 1 :(得分:4)
周期性域中两点之间的最短距离可以如下计算,而不使用任何循环。
dx = x2-x1
dx = dx - x_width*ANINT(dx/x_width)
这将给出签名的最短距离。 ANINT是一个内在的FORTRAN函数,使得ANINT(x)给出最接近的整数,其幅度小于abs(x)+0.5,其符号与x相同。例如,ANINT(0.51)= 1.0,ANINT(-0.51)= - 1.0等。其他语言也存在类似的函数。
答案 2 :(得分:3)
要找到值a
和a1
的新坐标的a2
- 轴中的最小增量,其中aBoundary
是a
的边界轴:
def delta(a1, a2, aBoundary):
return min(abs(a2 - a1), abs(a2 + aBoundary - a1))
因此,如果您有两个新坐标x1,y1
和x2,y2
的积分,您可以这样做:
sumOfSquares(delta(x1,x2,width), delta(y1,y2,height))
这实际上是你的建议,但我不会说这是“许多检查,计算和操作”。
答案 3 :(得分:0)
(delta_x, delta_y)=
(min(width - abs(x_new - x_new), abs(x_new - x_old)),
min(height - abs(y_new - y_old), abs(y_new - y_old)))
答案 4 :(得分:0)
距离不能大于宽度/ 2和高度/ 2。如果得到的差值(X1-X2)大于宽度/ 2,则减去宽度/ 2以获得快捷距离。然后像往常一样计算距离。
答案 5 :(得分:0)
男人我做了不同的事情......
这里有一点额外的功能,但核心是包裹屏幕上的距离......
longname
答案 6 :(得分:-1)
你不能在mod操作符中使用“abs”函数!
xd =(x1-x2+Width)%Width
yd=(y1-y2+Height)%Height
D=sqrt(xd^2+yd^2)