更新一个点的位置

时间:2010-01-25 10:45:29

标签: c algorithm math

我的问题是:

我在3D空间中有一组点,它们的位置会不时以一定的速度更新。但我需要保持它们之间的最小距离。

你能帮我解决这个问题吗?

编辑:我使用C来实现算法。

提前致谢。

5 个答案:

答案 0 :(得分:1)

如果您想保持最小距离 d ,您可以始终假设这些点由半径 d / 2的刚性球组成。因此,只要有2个球接触(即距离≤ d ),就会在弹性碰撞时改变速度。查看物理教科书,了解弹性碰撞时如何改变速度。

(您可能需要实现四叉树以进行有效的碰撞检测。)

答案 1 :(得分:1)

您也可以使用物理模拟来完成此操作。这提供了更多的可能性,但计算成本更高。

例如,其他人建议检测碰撞,但在您对duffymo的评论中,您建议您可能希望平滑减速以避免碰撞。在这种情况下,您可以创建一个粒子间力量将它们彼此远离,然后使用 a = F / m计算每个时间步的速度,并且 v = v0 + dt a ,其中 F 是所有粒子彼此之间的力的总和。对于一个示例粒子间力量,您可以使用看起来像这样的东西: alt text http://i46.tinypic.com/13zcxlt.png

根据下面的Python代码计算。但是,只要它在你的最小距离附近足够大(所以点永远不会靠近在一起),任何东西都可以工作,并且它超过一定距离(因此这些点并不总是彼此排斥)。

from pylab import *

def repulse(x, c, rmin=1., fmax=100):
    if x<=rmin:
        return fmax
    try:
        f = c/(x-rmin)-5.
        if f<0.:
            f = 0.
        if f>fmax:
            return fmax        
    except:
        f = fmax
    return f

x = arange(0, 100, .01)
r = 0.*x
for c in range(0, 10):
    for i, xv in enumerate(x):
        r[i] = repulse(xv, 2.**c)
    plot(x, r)
show()

答案 2 :(得分:0)

给定速度更新位置很简单 - 只需使用速度的一阶差分并计算时间步结束时的位置。

“但我需要保持它们之间的最小距离” - 完全没有意义。它们之间的距离将取决于为您提供速度矢量的过程的物理过程。你能描述一下你想要做什么吗?

答案 3 :(得分:0)

您需要做的第一件事就是检测2点之间的距离是否小于最小距离。第二个是移动点以消除碰撞。

第一部分基本上是圆到圆的碰撞*检测,所以方法是相同的:检查每个移动点与其他点之间的距离,或者使用连续的碰撞检测*(如果点通过一些简单的定律移动)。 / p>

第二部分取决于你,有太多方法。

(*) - googleable

答案 4 :(得分:0)

确定两个粒子是否会碰撞。假设你有两个粒子A和B,你知道它们在0时刻的位置和它们的速度。最初它们距离 r 的距离更远;你想知道他们是否以及何时会进入彼此的 r

让我们定义两个3D矢量 R V R =时间0处B相对于A的位置B.position - A.position V = B相对于A的速度B.velocity - A.velocity。时间 t 之间A和B之间距离的平方将为

square_of_distance(t)
    = abs(R + V*t)^2
    = dot(R + V*t, R + V*t)
    = dot(R, R) + 2 * dot(R, V*t) + dot(V*t, V*t)
    = dot(R, R) + 2 * dot(R, V) * t + dot(V, V) * t^2

其中dot(v1,v2)是两个向量的dot product,abs(v)是vector length

这是 t 的简单二次函数。使用quadratic formula,当square_of_distance( t )= r 2时,您可以找到 t 的时间(如果有) 。这将告诉您粒子是否以及何时比 r 更接近彼此。

确定首先碰撞大量粒子中的哪一个。当然,您可以采取所有可能的粒子对并计算它们何时发生碰撞。那是O( n 2 )。对此的改进比我们到目前为止所做的简单工作更难。

由于您只需要知道下一个,比如 n 秒,您可以为该时间段内每个粒子的路径计算bounding box,将所有这些框扩展为 r 在每个方向上,看看哪些重叠。这可以使用修改后的kd-tree来完成。重叠的边界框不一定表示实际的碰撞,只表示潜在的碰撞。这些潜在的碰撞仍然需要在数学上进行检查,以确定是否存在真正的碰撞;这只是一种将O( n 2 )的检查量减少到更易于管理的方法。