Unity_角度_弧度_向量-----(最近遇到一点这方面的小问题,发现有些遗忘了,特此温故,并摘抄了部分大佬们的优秀注释)
1,角度
两条相交直线中的任何一条与另一条相叠合时必须转动的量的量度,转动在这两条直线的所在平面上并绕交点进行。
角度是用以量度角的单位,符号为°。一周角分为360等份,每份定义为1度(1°)。
之所以采用360这数值,是因为它容易被整除。360除了1和自己,还有21个真因子(2、3、4、5、6、8、9、10、12、15、18、20、24、30、36、45、60、72、90、120、180),所以很多特殊的角的角度都是整数。
2.弧度
在数学和物理中,弧度是角的度量单位。它是由国际单位制导出的单位,单位缩写是rad。定义:弧长等于半径的弧,其所对的圆心角为1弧度。(即两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当这段弧长正好等于圆的半径时,两条射线的夹角的弧度为1)。
3.关系
角度和弧度关系是:2π弧度=360°。从而1°≈0.0174533弧度,1弧度≈57.29578°。
1) 角度转换为弧度公式:弧度=角度×(π ÷180 )
2)弧度转换为角度公式: 角度=弧度×(180÷π)
4.向量
点乘积的计算方式为:a*b=|a|*|b|*cos<a,b>,其中|a|和|b|表示向量的模,<a,b>表示两个向量的夹角。在点积中<a,b>和<b,a>夹角是不分顺序的。所以通过点积,可以计算两个向量的夹角。
还可以粗略的判断当前物体是否朝向另一个物体,或者说物体是否在我的前面(后面)。只需要计算
Vector3 selfforward = self.transform.forward;
Vector3 selftotarget = (target.transform.position - self.transform.position).normalized;
的点积即可,结果大于0则目标在我前方。
叉积定义:c = a x b,其中a b c均为向量,即两个向量的叉积结果还是一个向量。
性质1:c⊥a,c⊥b,即向量c垂直于向量a b所在平面。
性质2:模长|c|=|a|*|b|*sin<a,b>。
性质3:满足右手法则。有a x b ≠ b x a,而a x b = - b x a。
简单的说: 点乘判断角度,叉乘判断方向。 叉乘可以判断你是往左转还是往右转更好的转向敌人,点乘得到你当前的面朝向的方向和你到敌人的方向的所成的角度大小。
代码如下:
using UnityEngine; public class Vector3Test : MonoBehaviour { private Vector3 a = new Vector3(1, 0, 1); private Vector3 b = new Vector3(-2, 0, -2); private void Start() { //--向量点乘--结果为一个数值 float value = Vector3.Dot(a, b); //Debug.Log(value); float radians = Mathf.Acos(Vector3.Dot(a.normalized, b.normalized));//--弧度 //Debug.Log(radians); float degrees = radians * Mathf.Rad2Deg;//--角度 //Debug.Log(degrees); float angle = Vector3.Angle(a, b);//--角度 //Debug.Log(angle); //--向量叉乘--结果是一个向量 Vector3 e = Vector3.Cross(a, b); //Debug.Log(e.y); Vector3 f = Vector3.Cross(b, a); float degrees1 = Mathf.Asin(Vector3.Cross(a.normalized, b.normalized).magnitude) * Mathf.Rad2Deg; //Debug.Log(e); //Debug.Log(f); // Debug.Log(degrees1); TestDot(a, b); TestCross(a, b); GetAngle(a, b); } //点积 private void TestDot(Vector3 a, Vector3 b) { float result = Vector3.Dot(a, b); if (result > 0) { Debug.Log("b在a前"); } else if (result == 0) { Debug.Log("ab垂直"); } else { Debug.Log("b在a后"); } float angle = Vector3.Angle(a, b);//[0 - 180] result = Vector3.Dot(a.normalized, b.normalized); float radians = Mathf.Acos(result); angle = radians * Mathf.Rad2Deg; } //叉乘 private void TestCross(Vector3 a, Vector3 b) { Vector3 c = Vector3.Cross(a, b); if (c == Vector3.zero) { Debug.Log("b和a(平行),夹角:" + Vector3.Angle(a, b)); return; } float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a.normalized, b.normalized))); float angle = radians * Mathf.Rad2Deg; // 判断顺时针、逆时针方向,是在 2D 平面内的,所以需指定一个平面 //下面以X、Z轴组成的平面为例 , (Y 轴为纵轴), // 在 X、Z 轴平面上,判断 b 在 a 的顺时针或者逆时针方向, if (c.y > 0) { Debug.Log("b在a的顺时针方向"); } else if (c.y == 0) { //-- } else { Debug.Log("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); } }
参考:https://blog.csdn.net/yupu56/article/details/53609028
原文地址:https://www.cnblogs.com/Roz-001/p/12144423.html
- Python调用C函数的方法以及如何编写Python的C扩展
- C# 中使用 RSA加解密算法
- Tensorflow实践:用神经网络训练分类器
- 理解闭包 js回收机制
- java 解析 XML实例
- Java 线程内异常处理
- Raphael path 拖动实现
- 黑猿大叔-译文 | TensorFlow实现Batch Normalization
- Java后端WebSocket的Tomcat实现
- jwplayer 隐藏属性方法记载
- TensorFlow从0到1丨开篇:Hello TensorFlow !
- JS原型继承和类式继承
- 在Servlet的init方法中创建线程
- TensorFlow从0到1丨第2篇:TensorFlow核心编程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux下使用 github+hexo 搭建个人博客02-hexo部署到Github Pages
- Linux下使用 github+hexo 搭建个人博客03-hexo配置优化
- 接口测试框架实战(五) | 测试数据的数据驱动
- Linux下使用 github+hexo 搭建个人博客04-next主题优化
- Linux下使用 github+hexo 搭建个人博客05-next主题接入评论系统 来必力畅言Valine获取 livere_uid在Next主题配置浏览器访问数据
- Linux下使用 github+hexo 搭建个人博客06-next主题接入数据统计
- egg.js 动态转发代理
- Linux下使用 github+hexo 搭建个人博客07-next主题接入搜索和站点管理
- Linux curl 命令详解
- Linux curl 常用示例
- Linux curl 表单登录或提交与cookie使用
- Rsync 服务部署与参数详解
- Linux 查看磁盘IO并找出占用IO读写很高的进程
- Linux tcpdump 命令详解与示例
- 手动搭建Hadoop分布式集群