我正在创建一个函数,使用点积公式计算 Unity 游戏的 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
。我尝试并检查了代码和公式,但空手而归。
有人可以帮助我吗?提前谢谢您!!
最佳答案
float.NaN
是未定义(对于实数)数学运算的结果,例如 0/0
(文档中的注释是 x/0
其中 x != 0
code> 相反返回正无穷大或负无穷大)或负值的平方根。一旦运算中的一个操作符已经是 NaN
,那么整个运算也会再次返回 NaN
。
第二个(负值的平方根)在这里不会发生,因为您使用的是平方值,所以很可能您的向量的大小为 0
。
如果你看Vector2
source code你会发现他们的 Vector2.Angle
的实现或Vector2.SignedAngle
(顺便说一句,您应该使用它们,因为它们已经过测试并且效率更高)。
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
关于c# - 为什么我的 2 个向量角度函数返回 NaN,即使我遵循公式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68843016/