因此,我了解到在编程中使用平方根总是不好的做法,尤其是在每个更新步骤中。我正在尝试在圆之间进行逼真的弹性碰撞,并且我一直在阅读以下内容:http : //www.vobarian.com/collisions/2dcollisions2.pdf是否可以在不使用平方根的情况下标准化向量?还是做我正在做的任何快速方法?
乘以 大小平方的快速逆平方根进行归一化。
归一化向量意味着将其每个分量除以该向量的大小。大小等于sqrt(x**2 + y**2),其中x和y是向量的分量。但是平方根很慢,我们宁愿避免。因此,sqrt(x**2 + y**2)我们选择乘以幅度的反平方根,而不是除以1 / sqrt(x**2 + y**2)。
sqrt(x**2 + y**2)
x
y
1 / sqrt(x**2 + y**2)
为什么有帮助?因为制作Quake III的优秀人才提出了一种非常快速的计算方法1 / sqrt(x**2 + y**2),我们称之为 快速逆平方根 。
换句话说,fisqrt(x)等于1 / sqrt(x),但是计算fisqrt(x)比计算快得多1 / sqrt(x)。
fisqrt(x)
1 / sqrt(x)
这是一些伪python来说明如何将它们组合在一起。
def fisqrt(x): # See article for implementation details. def normalize(vector): magnitude_squared = vector.x**2 + vector.y**2 invsqrt = fisqrt(magnitude_squared) vector.v *= invsqrt vector.y *= invsqrt return vector
另外,您可以“剔除”更昂贵的碰撞检查(以下为伪python):
def magnitudeSquared(vector): return vector.x ** 2 + vector.y ** 2 def cull(circleA, circleB): # Save a square root by calling magnitudeSquared. # Assuming that circle.center is a vector with x and y components. minCollisionDistance = circleA.radius + circleB.radius if magnitudeSquared(circleA.center - circleB.center) <= minCollisionDistance ** 2: # Circles overlap, can't cull. return false # Circles do not overlap, can cull! return true
cull在进行其他碰撞检查之前先致电。当cull返回true时,您不需要做任何进一步的检查,因为两个圆圈不可能彼此接触。很好,因为它cull几乎肯定会比您可能使用的其他碰撞检测方法快。如果cull返回假,则圆的面积在某处重叠,因此您可以调用更昂贵的物理建模算法。
cull