我的游戏窗口大小为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。考虑到包裹。
我是否可以使用其他功能,或者可以在考虑包装之前/之后进行一些转换?
答案 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.pdist的Y = pdist(X, func)
描述中显示的最后一种调用形式
您应该能够使用该功能使pdist
根据应用{{1的回调函数计算出的距离来建立所有点对之间的距离矩阵}}计算。
答案 1 :(得分:0)
让我们假设您将四个板块复制到原始板块的上方,下方,左侧和右侧,并将原始板块上的粒子复制到新板上。我们还要标记粒子。
表示原始板N
,o(i)
从i
和1
开始的N
粒子。 a(i)
用于上面复制的板上的粒子。 b(i)
,l(i)
,r(i)
分别位于下方,左侧和右侧。
对于所有不同的i
和j
,您需要找到o(i)
和o(j)
,o(i)
和a(j)
等之间的距离,等等。每对i
和j
的距离为5x5 = 25。一旦拥有所有这些距离,就以每对中的最小值为准,即i
和j
的距离。
我当时想可能有一些方法可以简化计算。但是我的想法是,您至少需要计算粒子与边界之间的距离,并将其与原始电路板上的距离进行比较。这也是开销。