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

本文探讨了如何在项目中控制角色根据鼠标点击位置在8个方向上移动的问题。通过计算两个触点间向量与向上向量之间的夹角,确定角色应该采用的图集方向。介绍了两种方法:一种是使用Vector2.Angle结合叉乘判断角度范围;另一种是使用Vector2.SignedAngle直接获取带符号的角度。

问题

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

项目需要控制角色在地图中随意移动,角色素材是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(www.dongfan178.com/ toVector2,Vector2.up);
var cross = Vector3.Cross(www.fencaiyule.cn toVector2,Vector2.up);

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

方法二:

var angle = Vector2.SignedAngle(toVector2, Vector2.up);
if (angle <www.leyou2.net 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 www.taohuaqing178.com/ sin@.

c的模 也就是 z

然后再根据正弦函数

Sin取值范围

可以知道. 当sin@<0 时候 也就是此时得到角度是大于180的.

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

方法二

WX20180630-011249

直接进到其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)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值