求两向量在0~360度之间的角度值及实际应用

Posted eran

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求两向量在0~360度之间的角度值及实际应用相关的知识,希望对你有一定的参考价值。

实际应用

技术分享图片

问题

先从实际问题出发,这样可以更好的理解问题.

项目需要控制角色在地图中随意移动,角色素材是8方向的. 那问题就是

如何根据点击的鼠标位置来决定使用哪个方向的图集?

分解问题

  • 首先8方向图集 360/8 = 45 也就是每45度一个图集. 然要注意起始角度并不是0度.

    不是0~45度 是图集A, 而应该是 -22.5~22.5 是图集A ,22.5 ~ 67.5(22.5+45) 是图集B 以此类推

  • 根据当前Touch(PosB),和上次Touch(PosA) 做一个向量AB , 只要求的该向量AB和Up向量(Vector2.up)之间的夹角即可

方法

方法一:

var angle = Vector2.Angle(toVector2,Vector2.up);
var cross = Vector3.Cross(toVector2,Vector2.up);

if (cross.z < 0)
{
   angle = 360 - angle;
}

方法二:

var angle = Vector2.SignedAngle(toVector2, Vector2.up);
if (angle < 0)
{
    angle = 360 + angle;
}

方法一

方法一是之前一直使用的,方法二是后来发现API中有的.也许是新加入的?(2017.1).

先从方法一说起.

首先是

var angle = Vector2.Angle(Vector2.up, toVector2);

取得角度这个方法,这个是无符号的.官网的API文档说的很清楚了

The angle returned is the unsigned acute angle between the two vectors. This means the smaller of the two possible angles between the two vectors is used. The result is never greater than 180 degrees.

也就是能取到的是最小夹角,比如返回一个30度. 你无法知道是30度还是330度(360-30).

这个就需要使用到 叉乘来判断了.

技术分享图片

首先 叉乘 只能用于3D向量,但是确实又允许Vector3.Cross(Vector2.up, toVector2)这么写.

这个就可以把 Vector2.uptoVector2看成x-y平面的向量,其z=0.

那么他的叉积就是和z轴共线的向量

技术分享图片

因为,Vector2.uptoVector2的z均为零,所以

两向量叉乘得到向量为(0,0,z)

同时又根据上面的公式 c的模=a的模 x b的模 x [email protected]

c的模 也就是 z

然后再根据正弦函数

技术分享图片

可以知道. 当[email protected]<0 时候 也就是此时得到角度是大于180的.

比如上面angle给出来的是30度, 那么就需要用 360-30 得到 330度.

方法二

技术分享图片

直接进到其API的实现就可以看到了

  • 红框部分就是 var angle = Vector2.Angle(Vector2.up, toVector2);
  • 篮框部分就是 z

叉积向量

x = y1z2 - z1y2
y = z1x2 - x1z2
z = x1y2 - y1x2

因为z1和z2都是0,所以叉积就是向量(0,0,x1y2 - y1x2)

换句话说就是 方法二 其实就是封装后的 方法一



以上是关于求两向量在0~360度之间的角度值及实际应用的主要内容,如果未能解决你的问题,请参考以下文章

试图找到两个向量之间的角度(三角形)(HTML5 Canvas)

Spark笔记(1) :余弦相似度计算

企业遇到什么问题有必要做360度评估?

弧度和角度的换算

角度与弧度的换算公式?

Unity_角度_弧度_向量-----(最近遇到一点这方面的小问题,发现有些遗忘了,特此温故,并摘抄了部分大佬们的优秀注释)