Unity 点乘(Dot)、叉乘(Cross)判断移动方向、朝向等向量问题
2015-12-16 19:18
1176 查看
Unity 点乘(Dot)、叉乘(Cross)判断移动方向、朝向等向量问题
项目中常会用到物体移动,追踪,判断两物体移动方向是否相同,两物体移动方向夹角,以及物体 A 朝 物体 B 顺时针方向还是逆时针方向移动。物体 A 在 物体 B 的前后左右方向。下面通过点乘(Dot)、叉乘(Cross), 得到上面的需求结果。
代码如下
using UnityEngine; using System.Collections; public class VectorDotCross : MonoBehaviour { // 关于点积 private void Dot() { /* 点积 点积的计算方式为: a·b=|a|·|b|cos<a,b> 其中|a|和|b|表示向量的模, <a,b>表示两个向量的夹角。 通过点积判断当两个向量的方向向是否相同 (大致相同即两个向量的夹角在 90 度范围内) 两个向量的 点积 大于 0 则两个向量夹角小于 90 度, 否则 两个向量的 夹角大于 90 度, */ // 定义两个向量 a、b Vector3 a = new Vector3(1, 1, 1); Vector3 b = new Vector3(1, 5, 1); // 计算 a、b 点积结果 float result = Vector3.Dot(a, b); // 通过向量直接获取两个向量的夹角(默认为 角度), 此方法范围 [0 - 180] float angle = Vector3.Angle(a, b); // 下面获取夹角的方法,只是展示用法,太麻烦不必使用 // 通过向量点积获取向量夹角,需要注意,必须将向量转换为单位向量才行 // 计算 a、b 单位向量的点积 result = Vector3.Dot(a.normalized, b.normalized); // 通过反余弦函数获取 向量 a、b 夹角(默认为 弧度) float radians = Mathf.Acos(result); // 将弧度转换为 角度 angle = radians * Mathf.Rad2Deg; } // 关于叉乘 private void Cross() { /* 叉积 叉积的定义: c = a x b 其中a,b,c均为向量。两个向量的叉积是向量, 向量的模为 |c|=|a||b|sin<a,b> 且 向量 c 垂直于 a、b, c 垂直于 a、b 组成的平面, a x b = - b x a; */ // 定义两个向量 a、b Vector3 a = new Vector3(1, 1, 1); Vector3 b = new Vector3(1, 5, 1); //计算向量 a、b 的叉积,结果为 向量 Vector3 c = Vector3.Cross(a, b); // 下面获取夹角的方法,只是展示用法,太麻烦不必使用 // 通过反正弦函数获取向量 a、b 夹角(默认为弧度) float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a.normalized, b.normalized))); float angle = radians * Mathf.Rad2Deg; // 判断顺时针、逆时针方向,是在 2D 平面内的,所以需指定一个平面,下面以X、Z轴组成的平面为例(忽略 Y 轴) // 以 Y 轴为纵轴 // 在 X、Z 轴平面上,判断 b 在 a 的顺时针或者逆时针方向 if (c.y > 0) { // b 在 a 的顺时针方向 } else if (c.y == 0) { // b 和 a 方向相同(平行) } else { // b 在 a 的逆时针方向 } } // 获取两个向量的夹角 Vector3.Angle 只能返回 [0, 180] 的值 // 如真实情况下向量 a 到 b 的夹角(80 度)则 b 到 a 的夹角是(-80) // 通过 Dot、Cross 结合获取到 a 到 b, b 到 a 的不同夹角 private void GetAngle(Vector3 a, Vector3 b) { Vector3 c = Vector3.Cross(a, b); float angle = Vector3.Angle(a, b); // b 到 a 的夹角 float sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(a.normalized, b.normalized))); float signed_angle = angle * sign; Debug.Log("b -> a :" + signed_angle); // a 到 b 的夹角 sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(b.normalized, a.normalized))); signed_angle = angle * sign; Debug.Log("a -> b :" + signed_angle); } }
相关文章推荐
- unity5 animator过渡速度变化
- Unity3D -- 保存数据到excel
- 懵懵懂懂开始学习Unity
- Unity常见问题集(待续)
- Unity3D -- 从excel文件中读取数据
- unity3d结合轮廓显示,实现完整的框选目标(附Demo代码)
- Unity Text 插入超链接
- Unity3d 工具打包完 自动上传到FTP服务器
- Unity 点击模型上任意位置,模型旋转,点击位置朝向摄像机
- unity3d 嵌入iOS的 In App Purchase 应用程序内购买
- Unity的四种坐标系
- 项目记录11---unity热更新探讨
- unity3d ulua class
- Unity Networking API文档翻译(二):The High Level API
- 我的Unity日记
- Unity批处理脚本
- Unity质量设置 Quality Settings
- 利用NDK 生成.so文件
- MySQL Community Server 5.7 的数据备份
- Unity3D中的系统调用方法