当前位置:   article > 正文

Unity中的数学基础知识---向量的基础应用_unity sqrmagnitude

unity sqrmagnitude

一、向量的减法

①获取两个物体之间的距离(使用向量的模判断)

注意:Unity3D中的模可以直接使用向量的magnitude属性直接获得,如果不需要开平方根,可以使用向量的sqrMagnitude获得,这样,在一些不需要直接获取向量的模的时候可以减少运算量,因为平方根比较消耗计算时间。

  1. /***
  2. *
  3. * Title: 第16章 3D数学
  4. * Description:
  5. * 功能:向量的减法
  6. * Date: 2019
  7. * Version: 1.0
  8. * Modify Recorder:
  9. *
  10. */
  11. using UnityEngine;
  12. using System.Collections;
  13. public class Demo1 : MonoBehaviour {
  14. public Transform traOther; //其他物体
  15. private float _FloCloseDistance=5.0F; //设定限制接近的最小距离
  16. void Update ()
  17. {
  18. if (traOther)
  19. {
  20. //使用向量减法( other.position - transform.position)获得两个对象之间的向量
  21. var sqrLen = (traOther.position - transform.position).sqrMagnitude;
  22. // 使用sqrMagnitude取代Magnitude来计算距离,提高运算效率
  23. if (sqrLen < _FloCloseDistance * _FloCloseDistance)
  24. {
  25. print("其他物体太接近我了!");
  26. }
  27. else {
  28. print("其他物体距离很远,目前很安全!");
  29. }
  30. }
  31. }
  32. }

②获取两个物体之间的距离(可以使用Unity向量类中的Distance(Vector3 a,Vector3 b)函数 )

  1. /// <summary>
  2. /// 获取到两个物体之间的距离
  3. /// </summary>
  4. /// <param name="targetObj">目标对象</param>
  5. /// <param name="needMoveObj">需要移动的对象</param>
  6. /// <returns></returns>
  7. public float GetDistance(Transform targetObj,Transform needMoveObj,int Method=1)
  8. {
  9. float distance=0;
  10. if (targetObj!=null && needMoveObj!=null)
  11. {
  12. switch (Method)
  13. {
  14. case 1:
  15. distance = Vector3.Distance(targetObj.position, needMoveObj.position);
  16. break;
  17. case 2:
  18. 获取到模的平方
  19. //distance = (targetObj.position - needMoveObj.position).sqrMagnitude;
  20. //获取到模的长度(消耗资源)
  21. distance = (targetObj.position - needMoveObj.position).magnitude;
  22. break;
  23. default:
  24. break;
  25. }
  26. }
  27. return distance;
  28. }

二、向量的加法

两个向量的维数必须相同,才能够相加减。

意义:向量a加向量b解释为:平移向量,使向量a的头连接向量b的尾,接着从a的尾向b的头画出一个向量(也叫三角形法则)

三、对向量进行单位化 (获取方向)

意义:只关心向量方向而不关心大小,比如飞机的朝向,某个面的法线朝向等。

单位向量就是大小为1的向量,它经常也被称为标准化向量、法线(Normal)或者归一化

单位化向量=向量/向量的模(且向量的模不等于0),可以使用Unity中的normalized属性或者Normalize()函数将向量单位化

  1. Vector3 goNormalVec1 = Vector3.Normalize(gameObject.transform.position);
  2. Vector3 goNormalVec2 = gameObject.transform.position.normalized;
  3. Debug.Log("Vector3.Normalize方法物体的单位向量=" + goNormalVec1);
  4. Debug.Log("normalized属性物体的单位向量=" + goNormalVec2);

、向量与标量相乘(实现移动)

向量乘以标量K的效果是以因子|K|缩放向量的长度;如若果K<0,则向量除了做缩放操作外还使得向量方向倒转。

  1. /***
  2. *
  3. * Title: 第16章 3D数学
  4. *
  5. * Description:
  6. * 功能:向量与标量的乘法
  7. *
  8. * Date: 2019
  9. * Version: 1.0
  10. * Modify Recorder:
  11. *
  12. */
  13. using UnityEngine;
  14. using System.Collections;
  15. public class Demo2 : MonoBehaviour
  16. {
  17. public Vector3 speedDirection; //速度
  18. public float speedScale=1F; //加速比率
  19. void Update ()
  20. {
  21. gameObject.transform.position += speedDirection * speedScale*Time.deltaTime;
  22. }
  23. }
  1. /// <summary>
  2. /// 移动到目标点(跟随目标)
  3. /// </summary>
  4. /// <param name="targetObj">目标对象</param>
  5. /// <param name="needMoveObj">需要移动的对象</param>
  6. public void MoveToTargetPostion(Transform targetObj,Transform needMoveObj,float moveSpeed=0.5F)
  7. {
  8. if (targetObj!=null && needMoveObj != null && moveSpeed>=0)
  9. {
  10. //先计算二者方向
  11. Vector3 dir = (targetObj.position - needMoveObj.position).normalized;
  12. //物体从当前位置移动到目标位置
  13. needMoveObj.position += dir * Time.deltaTime * speed;
  14. }
  15. }

 

 

 五、向量的乘法

①向量的点乘

意义:点乘的计算结果给出了两个向量的相似程度,该相似度反映在两个向量之间的夹角上;

点乘结果越大,两个向量越接近;

点乘公式:a.b=||a|||b||cosθ==> θ = arccos(a·b)

如果只需知道a和b的夹角类型而不用知道该夹角的确切值,可以只根据所求出点乘结果的符号来判断

即a.b>0方向基本相同   a.b=0 a和b正交,相互垂直

  1. //测试点积
  2. private void TestDot(Vector3 a,Vector3 b)
  3. {
  4. //计算a,b点积结果
  5. float result = Vector3.Dot(a,b);
  6. Debug.Log("计算a,b点积结果="+result);
  7. //通过向量直接获取两个向量的夹角(默认是角度)该方法范围是[0-180]
  8. float angle = Vector3.Angle(a,b);
  9. Debug.Log("通过向量计算a,b向量夹角=" + angle);
  10. //计算a、b单位向量的点积,得到夹角余弦值|a.normalized|*|b.normalized|=1
  11. result = Vector3.Dot(a.normalized,b.normalized);
  12. Debug.Log("计算a,b单位向量的点积得到的余弦值=" + result);
  13. //通过反余弦函数获取向量a、b夹角(默认是弧度)
  14. float radians = Mathf.Acos(result);
  15. Debug.Log("反余弦计算a,b夹角=" + radians);
  16. //将弧度转换为角度
  17. angle = radians * Mathf.Rad2Deg;
  18. Debug.Log("计算反余弦计算a,b角度=" + angle);
  19. }
  1. /***
  2. *
  3. * Title:
  4. * 第16章 3D数学
  5. *
  6. * Description:
  7. * 功能:
  8. * 学习向量的“点乘”
  9. * 估算两个游戏对象的夹角角度。
  10. *
  11. * Date: 2017
  12. *
  13. * Version: 1.0
  14. *
  15. * Modify Recorder:
  16. *
  17. */
  18. using UnityEngine;
  19. using System.Collections;
  20. public class Demo3: MonoBehaviour {
  21. public Transform TraOther; //其他物体的方位
  22. private Vector3 _VecForward; //前方
  23. private Vector3 _VecToOther; //其他方向
  24. void Update () {
  25. if (TraOther){
  26. //使用TransformDirection把当前对象的正面朝向从局部坐标系转换到世界坐标系下,使得该向
  27. //量与其他对象的位置向量在世界坐标系下统一
  28. //Vector3.forward表示该对象当前的正方向向量
  29. _VecForward = transform.TransformDirection(Vector3.forward);
  30. //使用向量减法获得其他对象到当前对象之间的向量
  31. _VecToOther = TraOther.position - transform.position;
  32. //使用点乘计算结果的符号来判断其他对象是否在当前对象的后方
  33. if (Vector3.Dot(_VecForward, _VecToOther) > 0)
  34. {
  35. print("其他对象在我前方!");
  36. }
  37. else
  38. {
  39. print("其他对象在我后方。");
  40. }
  41. }
  42. }
  43. }
  1. /***
  2. *
  3. * Title:
  4. * 第16章 3D数学
  5. *
  6. * Description:
  7. * 功能:
  8. * 学习向量的“点乘”
  9. * 计算两个游戏对象的确切夹角角度。
  10. *
  11. * Date: 2017
  12. *
  13. * Version: 1.0
  14. *
  15. * Modify Recorder:
  16. *
  17. */
  18. using UnityEngine;
  19. using System.Collections;
  20. public class Demo4: MonoBehaviour {
  21. public Transform TraTarget; //目标
  22. private Vector3 _VecTargetDir;
  23. private Vector3 _VecForward;
  24. private float _FloAngle;
  25. /* 当对象的朝向与目标对象夹角小于5时,打印“视线靠近了”信息 */
  26. void Update () {
  27. //使用向量减法获得当前对象与目标对象之间的向量
  28. _VecTargetDir = TraTarget.position - transform.position;
  29. //当前对象的正方向向量
  30. _VecForward = transform.forward;
  31. //求出targetDir和forward向量之间的夹角值
  32. _FloAngle = Vector3.Angle(_VecTargetDir, _VecForward);
  33. //判断该夹角是否小于5
  34. if (_FloAngle < 5.0)
  35. {
  36. print("视线靠近了!");
  37. }
  38. else {
  39. print("视线没有靠近。");
  40. }
  41. }
  42. }

 ②向量的叉乘

意义:叉乘计算的结果是向量,该向量垂直于原来的两个向量

Vector3 normal = Vector3.Cross (fromVector,toVector);//叉乘求出法线向量 

angle *= Mathf.Sign (Vector3.Dot(normal,upVector));  //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 

计算出平面的法向量

  1. Vector3 side1=b-a;
  2. Vector3 side2=c-a;
  3. Vector3 Normal=Vector3.Cross(side1,side2);
  4. Normal.Normalize();
  1. //叉乘
  2. private void TestCross(Vector3 a, Vector3 b)
  3. {
  4. //计算向量 a、b 的叉积,结果为 向量
  5. Vector3 c = Vector3.Cross(a, b);
  6. // 通过反正弦函数获取向量 a、b 夹角(默认为弧度)
  7. float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a.normalized, b.normalized)));
  8. float angle = radians * Mathf.Rad2Deg;
  9. // 判断顺时针、逆时针方向,是在 2D 平面内的,所以需指定一个平面,
  10. //下面以X、Z轴组成的平面为例 , (Y 轴为纵轴),
  11. // 在 X、Z 轴平面上,判断 b 在 a 的顺时针或者逆时针方向,
  12. if (c.y > 0)
  13. {
  14. Debug.Log(" b 在 a 的顺时针方向");
  15. }
  16. else if (c.y == 0)
  17. {
  18. Debug.Log(" b 和 a 方向相同(平行)");
  19. }
  20. else
  21. {
  22. Debug.Log(" b 在 a 的逆时针方向");
  23. }
  24. }
  25. // 获取两个向量的夹角 Vector3.Angle 只能返回 [0, 180] 的值
  26. // 如真实情况下向量 a 到 b 的夹角(80 度)则 b 到 a 的夹角是(-80)
  27. // 通过 Dot、Cross 结合获取到 a 到 b, b 到 a 的不同夹角
  28. private void GetAngle(Vector3 a, Vector3 b)
  29. {
  30. Vector3 c = Vector3.Cross(a, b);
  31. float angle = Vector3.Angle(a, b);
  32. // b 到 a 的夹角
  33. float sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(a.normalized, b.normalized)));
  34. float signed_angle = angle * sign;
  35. Debug.Log("b -> a :" + signed_angle);
  36. // a 到 b 的夹角
  37. sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(b.normalized, a.normalized)));
  38. signed_angle = angle * sign;
  39. Debug.Log("a -> b :" + signed_angle);
  40. }

 注意:本内容参考:《Unity3D/2D游戏开发从0到1》第16章

                                    http://www.manew.com/youxizz/2982.html

                                    https://blog.csdn.net/yupu56/article/details/53609028

                                    https://blog.csdn.net/Game_jqd/article/details/78908152

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/86847
推荐阅读
相关标签
  

闽ICP备14008679号