Unity之向量

向量表示的是方向和大小,與位置距離無關


三維空間的表示如下


在unity3d中採用的struct來描述的Vector3

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. namespace UnityEngine  
  2. {  
  3.     public struct Vector3  
  4.     {  
  5.   
  6.         public float x;  
  7.         public float y;  
  8.         public float z;  
  9.          }  
  10. }  


向量的長度:向量的大小(或長度)稱爲向量的模


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public float magnitude  
  2. {  
  3.     get  
  4.     {  
  5.         return Mathf.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z);  
  6.     }  
  7. }  

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public float sqrMagnitude  
  2. {  
  3.     get  
  4.     {  
  5.         return this.x * this.x + this.y * this.y + this.z * this.z;  
  6.     }  
  7. }  


三維空間中兩點的距離

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static float Distance(Vector3 a, Vector3 b)  
  2. {  
  3.     Vector3 vector = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);  
  4.     return Mathf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);  
  5. }  


向量加法

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 operator +(Vector3 a, Vector3 b)  
  2. {  
  3.     return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);  
  4. }  


向量減法


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 operator -(Vector3 a, Vector3 b)  
  2. {  
  3.     return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);  
  4. }  


向量點積(dot product)又稱數量積或內積


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static float Dot(Vector3 lhs, Vector3 rhs)  
  2. {  
  3.     return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;  
  4. }  

根據公式A.B = |A||B|cos(a)得出兩個向量之間的弧度的角度

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static float AngleBetween(Vector3 from, Vector3 to)  
  2.     {  
  3.         return Mathf.Acos(Mathf.Clamp(Vector3.Dot(from.normalized, to.normalized), -1f, 1f));  
  4.     }  

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static float Angle(Vector3 from, Vector3 to)  
  2.     {  
  3.         return Mathf.Acos(Mathf.Clamp(Vector3.Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f;//角度  
  4.     }  

弧度=角度乘以π後再除以180

角度=弧度除以π再乘以180


其中a是A和B在3D空間中的夾角。如果已知兩個向量,使用數量積我們就可以通過計算求得兩個向量的夾角


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

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

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



向量叉積 :U和V的向量積(cross product,矢量積或外積)產生一個向量,它垂直於U和V,公式:U × V = n |U| |V| sin(a),其中n爲垂直於U和V的單位向量,a是U和V的夾角


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 Cross(Vector3 lhs, Vector3 rhs)  
  2. {  
  3.     return new Vector3(lhs.y * rhs.z - lhs.z * rhs.y, lhs.z * rhs.x - lhs.x * rhs.z, lhs.x * rhs.y - lhs.y * rhs.x);  
  4. }  


 判斷目標在自己的左右方位可以使用下面的方法:

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

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



數乘向量:實數λ與向量b的積是一個向量,記作:a=λb。規定:當λ爲正時,同向;當λ爲負時,反向;實數λ,叫做向量的係數。數乘向量的幾何意義就是把向量沿着相同方向或反方向放大或縮小

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 operator *(Vector3 a, float d)  
  2. {  
  3.     return new Vector3(a.x * d, a.y * d, a.z * d);  
  4. }  

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 operator *(float d, Vector3 a)  
  2. {  
  3.     return new Vector3(a.x * d, a.y * d, a.z * d);  
  4. }  

向量比較:

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static bool operator ==(Vector3 lhs, Vector3 rhs)  
  2. {  
  3.     return Vector3.SqrMagnitude(lhs - rhs) < 9.99999944E-11f;  
  4. }  
[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static bool operator !=(Vector3 lhs, Vector3 rhs)  
  2. {  
  3.     return Vector3.SqrMagnitude(lhs - rhs) >= 9.99999944E-11f;  
  4. }  

向量的規範化: 向量的規範化也稱(歸一化)就是使向量的模變爲1,即變爲單位向量。可以通過將向量都除以該向量的模來實現向量的規範化。規範化後的向量相當於與向量同方向的單位向量,可以用它表示向量的方向。由於方向的概念在3D編程中非常重要,所以此概念也很重要,單位向量有很多重要的性質,在表示物體表面的法線向量時用的更是頻繁 

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 Normalize(Vector3 value)  
  2. {  
  3.     float num = Vector3.Magnitude(value);  
  4.     if (num > 1E-05f)  
  5.     {  
  6.         return value / num;  
  7.     }  
  8.     return Vector3.zero;  
  9. }  


投影:一般用於透視,下圖u'是u在v上的投影,向量u和v的夾角爲theta,d就是u’的長度,而u’和v的方向是相同的,v/|v|也就是u’的方向

[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 Project(Vector3 vector, Vector3 onNormal)  
  2. {  
  3.     float num = Vector3.Dot(onNormal, onNormal);  
  4.     if (num < 1.17549435E-38f)  
  5.     {  
  6.         return Vector3.zero;  
  7.     }  
  8.     return onNormal * Vector3.Dot(vector, onNormal) / num;  
  9. }  

反射向量: 下圖入射光線向量I和平面法向量N,R爲反射向量,R=I-2(I.N)N

推導如下:

設入射光線向量I和反射平面的法向量N之間的夾角爲theta。連接I的始端和R的末端,則有R = 2P - I 

設入射點0到P與N的交點的向量爲S,那麼有P = I + S 

向量S即向量-N(注意,這裏是-N,因爲S和N的方向相反。)在向量N上的投影,根據向量的投影公式有,簡化後有:S=-(I.N)N,將R和P代入,有R=I-2(I.N)N


[csharp] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public static Vector3 Reflect(Vector3 inDirection, Vector3 inNormal)  
  2. {  
  3.     return -2f * Vector3.Dot(inNormal, inDirection) * inNormal + inDirection;  
  4. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章