【问题标题】:Normalizing Spatial Vectors without Square Root归一化没有平方根的空间向量
【发布时间】:2014-01-27 10:26:36
【问题描述】:

所以我了解到,在编程​​中使用平方根总是不好的做法,尤其是在每个更新步骤中。我正在尝试在圆之间进行逼真的弹性碰撞,我一直在阅读:http://www.vobarian.com/collisions/2dcollisions2.pdf 有没有一种方法可以在不使用平方根的情况下对向量进行归一化?或者有什么快速的方法来做我正在做的事情?

【问题讨论】:

    标签: java math collision geometry


    【解决方案1】:

    乘以要归一化的幅度平方的Fast Inverse Square Root

    对向量进行归一化意味着将其每个分量除以该向量的大小。幅度等于sqrt(x**2 + y**2),其中xy 是向量的分量。但是平方根很慢,我们宁愿避免它。因此,我们选择乘以幅度的倒数平方根,而不是除以sqrt(x**2 + y**2),即1 / sqrt(x**2 + y**2)

    为什么会有帮助?因为制作 Quake III 的好人想出了一个非常快速的方法来计算 1 / sqrt(x**2 + y**2),我们称之为快速平方根平方根

    换句话说,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 返回 false,则圆圈区域在某处重叠,因此您调用更昂贵的物理建模算法。

    【讨论】:

    • 你能举个例子吗?
    • 您希望我澄清什么?希望我能举个例子,让我知道不清楚的地方。
    • 我有一个函数可以找到平方根,但是如何从那个点对向量进行归一化?
    • 谢谢你,这是一个非常有帮助的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    相关资源
    最近更新 更多