Unity3D之點乘和差乘


一、向量

1、向量的數學定義

向量就是一個數字列表,對於程序員來說一個向量就是一個數組。 
向量的維度就是向量包含的“數”的數目,向量可以有任意正數維,標量可以被認為是一維向量。 
書寫向量時,用方括號將一列數括起來,如[1,2,3] 水平書寫的向量叫行向量 垂直書寫的向量叫做列向量 
2、向量的幾何意義

幾何意義上說,向量是有大小和方向的有向線段。向量的大小就是向量的長度(模)向量有非負的長度。 
向量的方向描述了空間中向量的指向。 
向量的形式:向量定義的兩大要素——大小和方向,有時候需要引用向量的頭和尾,下圖所示,箭頭是向量的末端,箭尾是向量的開始 
這里寫圖片描述 
向量中的數表達了向量在每個維度上的有向位移,例如2D向量列出的是沿x坐標方向和y坐標方向的位移。 
3 unity中的向量 Vector類 
Vector2 二維向量,表示 2D 的向量和點 
Vector3 三維向量,表示3D的向量和點 
Vector3.normalized 規范化,返回向量的長度為1(只讀)。 
Vector3.magnitude 長度,返回向量的長度(只讀)。 
Vector3.Angle 角度 , Angle (from : Vector3, to : Vector3) ,由from和to兩者返回一個角度。形象的說,from和to的連線和它們一個指定軸向的夾角

二、點乘

1 點乘的數學意義 
這里寫圖片描述
2 點乘的幾何意義 
這里寫圖片描述
3點乘的特點 
在向量u,向量v非零的前提下,點積如果為負,則u,v形成的角大於90度; 
如果為零,那么u,v垂直; 
如果為正,那么u,v形成的角小於90度。 
3 點乘在unity中的應用 
Vector3.Dot 點乘,對於normalized向量,如果他們指向在完全相同的方向,Dot返回1。如果他們指向完全相反的方向,返回-1。對於其他的情況返回一個數(例如:如果是垂直的Dot返回0)。對於任意長度的向量,Dot返回值是相同的:當向量之間的角度減小,它們得到更大的值。

三、叉乘

1 叉乘的數學意義 
表示方法 
兩個向量a和b的叉積寫作a×b(有時也被寫成a∧b,避免和字母x混淆)。 
定義 
向量積可以被定義為: 
模長:(在這里θ表示兩向量之間的夾角(共起點的前提下)(0° ≤ θ ≤ 180°),它位於這兩個矢量所定義的平面上。) 
這里寫圖片描述 
方向:a向量與b向量的向量積的方向與這兩個向量所在平面垂直,且遵守右手定則。(一個簡單的確定滿足“右手定則”的結果向量的方向的方法是這樣的:若坐標系是滿足右手定則的,當右手的四指從a以不超過180度的轉角轉向b時,豎起的大拇指指向是c的方向。)

也可以這樣定義(等效): 
向量積|c|=|a×b|=|a| |b|sin

四、點乘與叉乘在項目中的應用

項目需求: 
1 通過點乘計算物體B在物體A的前方還是后方 
2 通過叉乘,計算物體A轉向物體B時,最小角的旋轉方向

實現過程: 
首先計算出物體A的前方朝向向量v_Bz=B.transform.forward,然后計算物體B相對於物體A的位置向量 v_AB = A.position - B.position;

通過計算v_Bz與v_AB向量點乘結果的正負,判斷物體B在物體A的前后 
如果物體B在物體A前方, Vector3.Dot(v_Bz,v_AB)大於0 
如果物體B在物體A后方, Vector3.Dot(v_Bz,v_AB)小於0

通過計算v_Bz與v_AB向量叉乘的結果,判斷旋轉方向 
如果逆時針旋轉,v_C = Vector3.Cross(v_Bz, v_AB)為沿y軸負方向 
如果順時針旋轉,v_C = Vector3.Cross(v_Bz, v_AB)為沿y軸正方向

using UnityEngine; using System.Collections; public class Vector3_Dot : MonoBehaviour { public Transform A, B; Vector3 v_Bz, v_AB, v_A,v_B,v_C; string str = ""; // Use this for initialization void Start() { } // Update is called once per frame void Update() { //點乘 v_Bz = B.transform.forward;//B.transform.TransformDirection(Vector3.forward); v_AB = A.position - B.position; float f = Vector3.Dot(v_Bz,v_AB); if (f>0) { str = "A在B自身座標系的前方"; } else if (f<0) { str = "A在B自身座標系的后方"; } else { str = "A在B自身座標系的左前方或右方"; } //差乘 v_A = A.position; v_B = B.position; v_C = Vector3.Cross(v_Bz, v_AB); // A.Rotate(0,0,0); } void OnGUI() { GUI.Label(new Rect(10,10,200,60),str); } void OnDrawGizmos() { //差乘繪制相關線 Gizmos.color = Color.blue; Gizmos.DrawLine(-v_C,Vector3.zero); //點乘繪制相關線 Gizmos.color = Color.yellow; Gizmos.DrawLine(Vector3.zero,A.position); Gizmos.color = Color.yellow; Gizmos.DrawLine(Vector3.zero,B.position); Gizmos.color = Color.red; Gizmos.DrawLine(A.position, B.position); Gizmos.color = Color.red; Gizmos.DrawLine(Vector3.zero,v_AB); Gizmos.color = Color.green; // Gizmos.DrawLine(A.transform.position, Vector3.left); } } 

這里寫圖片描述 
總結: 
點乘可以判斷向量之間的夾角,叉乘可以判斷向量之間的方向在順時針還是逆時針方向

五判斷敵我方位

1.判斷目標在自己的前后方位可以使用下面的方法:

   Vector3.Dot(transform.forward, target.position-transform.position)

       返回值為正時,目標在自己的前方,反之在自己的后方

2.判斷目標在機子的左右方位可以使用下面的方法:

   Vector3.Cross(transform.forward, target.position-transform.position).y

      返回值為正時,目標在自己的右方,反之在自己的左方

 

A.點積 
  點積的計算方式為:  a·b=|a|·|b|cos<a,b>  其中|a|和|b|表示向量的模,<a,b>表示兩個向量的夾角。另外在 點積 中,<a,b>和<b,a> 夾角是不分順序的。 
  所以通過點積,我們其實是可以計算兩個向量的夾角的。 
  另外通過點積的計算我們可以簡單粗略的判斷當前物體是否朝向另外一個物體: 只需要計算當前物體的transform.forward向量與 otherObj.transform.position- transform.position的點積即可, 大於0則在前方,否則在后方。

B.叉積 
  叉積的定義: c =a x b  其中a,b,c均為向量。即兩個向量的叉積得到的還是向量!    性質1: c⊥a,c⊥b,即向量c垂直與向量a,b所在的平面 。    性質2: 模長|c|=|a||b|sin<a,b>    性質3: 滿足右手法則 。從這點我們有axb ≠ bxa,而axb = – bxa。所以我們可以使用叉積的y的正負值來判斷向量a,b的相對位置,即向量b是處於向量a的順時針方向還是逆時針方向

 

右手法則:右手的四指方向指向第一個矢量,屈向叉乘矢量的夾角方向(兩個矢量夾角方向取小於180°的方向),那么此時大拇指方向就是叉乘所得的叉乘矢量的方向.(大拇指應與食指成九十度)(注意:Unity當中使用左手,因為Unity使用的是左手坐標系)

 

 

數學上叉乘的右手法則

 

 

Unity當中叉乘的左手法則

 

 

 

Unity項目應用:

 

1.根據叉乘得到a,b向量的相對位置,和順時針或逆時針方位。

 

簡單的說: 點乘判斷角度,叉乘判斷方向。  形象的說: 當一個敵人在你身后的時候,叉乘可以判斷你是往左轉還是往右轉更好的轉向敵人,點乘得到你當前的面朝向的方向和你到敵人的方向的所成的角度大小。

 

2.得到a,b夾角的正弦值,計算向量的夾角(0,90),可以配合點乘和Angle方法計算出含正負的方向。

 

3.根據叉乘大小,得到a,b向量所形成的平行四邊形的面積大小,根據面積大小得到向量的相對大小。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM