如何有效计算环形空间中的距离?

时间:2019-03-28 13:14:09

标签: python numpy scipy

我的游戏窗口大小为640 x 480,其中填充有粒子,但是当粒子从一侧移到另一侧时,它会缠绕到另一侧(即,是环形的)。

我想计算每个粒子之间的距离,因为这将用于对每个粒子施加不同的力。

首先,我遍历每对粒子,然后重新缩放所有内容,以使第一个粒子居中,然后计算到第二个粒子的距离,但这运行起来非常慢。

然后我在scipy.spatial.distance中找到了一些函数,这些函数可以让我非常快速地计算所有点之间的距离,但是唯一的问题是它没有考虑回绕。

这是我当前的代码

from scipy.spatial.distance import pdist, squareform
...
distance = squareform(pdist([(p.x, p.y) for p in particles]))

这适用于中心附近的粒子,但是如果一个粒子位于(1,320),而另一个粒子位于(639,320),则它将其距离计算为638而不是2。考虑到包裹。

我是否可以使用其他功能,或者可以在考虑包装之前/之后进行一些转换?

2 个答案:

答案 0 :(得分:1)

您可以像这样计算x和y差异中较小的一个(窗口内差异与边缘交叉距离):

game_width = 640
game_height = 480

def smaller_xy(point1, point2):

    xdiff = abs(point1.x - point2.x)
    if xdiff > (game_width / 2):
        xdiff = game_width - xdiff

    ydiff = abs(point1.y - point2.y)
    if ydiff > (game_height / 2):
        ydiff = game_height - ydiff

    return xdiff, ydiff

也就是说,如果在x或y方向上的窗口内距离大于该方向上窗口大小的一半,则最好避开边缘-在这种情况下,该距离将是窗口该方向的尺寸减去原始的窗口内距离。

很明显,一旦有了x和y间距,就可以计算出点之间的距离为:

import math

small_x, small_y = smaller_xy(p1, p2)
least_distance = math.sqrt(small_x**2 + small_y**2)

但是,根据定义的力计算方式,您可能会发现您真正需要的只是距离的平方(仅(small_x**2 + small_y**2),因此可以避免寻找{{ 1}}。

要使其深入到sqrt中,请注意,scipy.pdist除了要点之外还可以通过函数参数来调用,例如:

pdist

这是https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.pdist.html#scipy.spatial.distance.pdistY = pdist(X, func) 描述中显示的最后一种调用形式

您应该能够使用该功能使pdist根据应用{{1的回调函数计算出的距离来建立所有点对之间的距离矩阵}}计算。

答案 1 :(得分:0)

让我们假设您将四个板块复制到原始板块的上方,下方,左侧和右侧,并将原始板块上的粒子复制到新板上。我们还要标记粒子。

表示原始板No(i)i1开始的N粒子。 a(i)用于上面复制的板上的粒子。 b(i)l(i)r(i)分别位于下方,左侧和右侧。

对于所有不同的ij,您需要找到o(i)o(j)o(i)a(j)等之间的距离,等等。每对ij的距离为5x5 = 25。一旦拥有所有这些距离,就以每对中的最小值为准,即ij的距离。

我当时想可能有一些方法可以简化计算。但是我的想法是,您至少需要计算粒子与边界之间的距离,并将其与原始电路板上的距离进行比较。这也是开销。