求两个向量之间的夹角
- 介绍
- Unity的API求向量夹角
- Vector3.Angle
- Vector3.SignedAngle
- 自定义获取方法
- 0-360度的夹角
- 总结
介绍
求两个向量之间的夹角方法有很多,比如说Unity中的Vector3.Angle,Vector3.SignedAngle等方法,具体在什么情况下使用这个还是得看这几个函数的结果是什么。
Unity的API求向量夹角
通过蓝线和红线来做对比有如下的例子,以及打印如下
Vector3.Angle
这个API会计算出来这两个向量的夹角,不带正负号且通过测试发现这个角度只是小于180度的夹角,也就是说只是计算正向最小夹角使用
Vector3.SignedAngle
这个API计算的是从from向量到to向量的夹角,并且需要一个轴向(比如我需要计算的是XZ轴的夹角,则我axis轴向我写Vector3.Up即可)。
通过检测发现这个方法是有正负号的,区间为[-180,180]之间。
也就是说想要计算有符号的夹角则可以使用这个方法。
自定义获取方法
/// <summary>
/// 计算夹角带有正负号
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="n"></param>
/// <returns></returns>
public float AngleSigned(Vector3 from, Vector3 to, Vector3 n)
{
return Mathf.Atan2(
Vector3.Dot(n, Vector3.Cross(from, to)),
Vector3.Dot(from, to)) * Mathf.Rad2Deg;
}
/// <summary>
/// 计算夹角带有正负号
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="dir"></param>
/// <returns></returns>
private float GetAngle(Vector3 a, Vector3 b, Vector3 dir)
{
float angle1 = Vector3.Angle(a, b); //求出两向量之间的夹角
Vector3 normal = Vector3.Cross(a, b);//叉乘求出法线向量
angle1 *= Mathf.Sign(Vector3.Dot(normal, dir)); //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向
return angle1;
}
上述我提供得这两个方法经过测试也是可行的。
第一种AngleSigned方法类似于Unity的原生API Vector3.SignedAngle
第二种GetAngle方法其实就是先计算出来正常的不带符号的角度,在去用叉乘计算一下是左侧还是右侧最终给计算出的角度加上了正负号。
0-360度的夹角
如果要计算0-360度的夹角,则完全可以将上面得到的[-180,180]的夹角判定为附属时+360,判定为正时则不处理,这样就得到了区间[0,360]的夹角
总结
以上是对计算角度的一些相关计算,如果有写的不对或者有更好的想法可以评论说下,感谢大家的支持和关注!