即使我遵循公式,为啥我的 2 个向量的角度函数返回 NaN
Posted
技术标签:
【中文标题】即使我遵循公式,为啥我的 2 个向量的角度函数返回 NaN【英文标题】:Why is my angle of 2 vectors function return NaN even though i follow the formula即使我遵循公式,为什么我的 2 个向量的角度函数返回 NaN 【发布时间】:2021-10-20 21:03:09 【问题描述】:我正在制作一个函数,使用点积公式为我的统一游戏计算 2 个给定向量之间的角度:
vector(a)*vector(b)=|vector(a)|*|vector(b)|*cos(the angle)
所以我认为角度等于
acos((vector(a)*vector(b))/(|vector(a)|*|vector(b)|))
这是我的代码:
float rotateAngle(Vector2 a,Vector2 b)
return Mathf.Acos((a.x * b.x + a.y * b.y) / ((Mathf.Sqrt(a.x * a.x + a.y * a.y)) * (Mathf.Sqrt(b.x * b.x + b.y * b.y)))) * (180 / Mathf.PI);
但是当我播放它时,控制台显示NaN
。我已经尝试并查看了代码和公式,但空手而归。
有人可以帮助我吗?提前谢谢你!
【问题讨论】:
【参考方案1】:float.NaN
是未定义(实数)数学运算的结果,例如 0 / 0
(请注意,x / 0
其中x != 0
返回正或负无穷大)或负数的平方根价值。只要一个操作中的一个操作员已经是NaN
,那么整个操作也会再次返回NaN
。
第二个(负值的平方根)不能在这里发生,因为您使用的是平方值,所以很可能您的向量的大小为 0
。
如果您查看Vector2
source code,您会发现他们实现了Vector2.Angle
或Vector2.SignedAngle
(您应该使用btw,因为它们已经过测试并且效率更高)。
public static float Angle(Vector2 from, Vector2 to) // sqrt(a) * sqrt(b) = sqrt(a * b) -- valid for real numbers float denominator = (float)Math.Sqrt(from.sqrMagnitude * to.sqrMagnitude); if (denominator < kEpsilonNormalSqrt) return 0F; float dot = Mathf.Clamp(Dot(from, to) / denominator, -1F, 1F); return (float)Math.Acos(dot) * Mathf.Rad2Deg; // Returns the signed angle in degrees between /from/ and /to/. Always returns the smallest possible angle public static float SignedAngle(Vector2 from, Vector2 to) float unsigned_angle = Angle(from, to); float sign = Mathf.Sign(from.x * to.y - from.y * to.x); return unsigned_angle * sign;
在那里你会发现他们检查的第一件事是
float denominator = (float)Math.Sqrt(from.sqrMagnitude * to.sqrMagnitude); if (denominator < kEpsilonNormalSqrt) return 0F;
这基本上可以确保两个给定向量都具有“足够大”的量级,尤其是不是0
的向量;)
长话短说:不要重新发明***,而是使用已经内置的 Vector2.Angle
或 Vector2.SignedAngle
【讨论】:
实际上我从一开始就尝试了 Vector2.SignedAngle 但它没有用。我刚刚重新检查了一下,结果发现我从和到的向量都搞砸了。非常感谢您的详细解释:D 经验教训:)【参考方案2】:NaN 通常是对浮点数进行无效数学运算的结果。一个常见的来源是除以零,所以我的猜测是向量是 0,0。
我还建议使用内置函数来计算标准化、长度/幅度、点等,这将使代码更易于阅读,并且编译器应该非常擅长优化此类代码。如果您需要进行任何额外的优化,请仅在完成一些测量后进行。
【讨论】:
啊啊啊是的,这就是问题所在!我的向量中有 1 个是 (0,0),所以它搞砸了。非常感谢,我也去找找这些内置函数:)以上是关于即使我遵循公式,为啥我的 2 个向量的角度函数返回 NaN的主要内容,如果未能解决你的问题,请参考以下文章