【Unity】向量點乘與叉乘
【參考原文】Unity3D之Vector3.Dot和Vector3.Cross的使用
【參考原文】Unity3D之點乘和差乘
在Unity3D中,Vector3.Dot表示求兩個向量的點積;Vector3.Cross表示求兩個向量的叉積。
點積計算的結果為數值,而叉積計算的結果為向量。兩者要注意區別開來。
簡單的說,點乘判斷角度,叉乘判斷方向。
形象的說當一個敵人在你身後的時候,叉乘可以判斷你是往左轉還是往右轉更好的轉向敵人,點乘得到你當前的面朝向的方向和你到敵人的方向的所成的角度大小。
1.點積
a·b=|a|·|b|cos<a,b>
- |a|和|b|表示向量的模
- <a,b>表示兩個向量的夾角。<a,b>和<b,a> 夾角是不分順序的。
- 通過點積可以計算兩個向量的夾角的。
如果兩個向量a,b均 為單位 向量 ,那麼a.b等於向量b在向量a方向上的投影的長度
應用
通過點積的計算我們可以簡單粗略的判斷當前物體是否朝向另外一個物體: 只需要計算當前物體的transform.forward向量與 (otherObj.transform.position – transform.position)的點積即可。
- 若結果 == 0,則兩向量互垂直 。
- 若結果 > 0 ,則兩向量夾角小於90°,當前物體面對
- 若結果 < 0 ,則兩向量夾角大於 90°,當前物體背對
2.叉積
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。所以我們可以使用叉積的正負值來判斷向量a,b的相對位置,即向量b是處於向量a的順時針方向還是逆時針方向。
求兩向量夾角
using UnityEngine;
using System.Collections;
public class MainScript : MonoBehaviour
{
//向量a
private Vector3 a;
//向量b
private Vector3 b;
void Start ()
{
//向量的初始化
a = new Vector3 (1, 2, 1);
b = new Vector3 (5, 6, 0);
}
void OnGUI ()
{
//點積的返回值
float c = Vector3.Dot (a, b);
//向量a,b的夾角,得到的值為弧度,我們將其轉換為角度,便於檢視!
float angle = Mathf.Acos (Vector3.Dot (a.normalized, b.normalized)) * Mathf.Rad2Deg;
GUILayout.Label ("向量a,b的點積為:" + c);
GUILayout.Label ("向量a,b的夾角為:" + angle);
//叉積的返回值
Vector3 e = Vector3.Cross (a, b);
Vector3 d = Vector3.Cross (b, a);
//向量a,b的夾角,得到的值為弧度,我們將其轉換為角度,便於檢視!
angle = Mathf.Asin (Vector3.Distance (Vector3.zero, Vector3.Cross (a.normalized, b.normalized))) * Mathf.Rad2Deg;
GUILayout.Label ("向量axb為:" + e);
GUILayout.Label ("向量bxa為:" + d);
GUILayout.Label ("向量a,b的夾角為:" + angle);
}
}
上面的示例中,我們定義了兩個向量a和b。分別求出了他們的點積和叉積,並通過點積和叉積來反過來計算他們的夾角。
這裡要說明的是:
1.a.normalized 和 b.normalized 表示的是兩個向量的單位向量, 因為在公式裡,有向量和模的除法,得出來的結果就是單位向量(單位向量模為1),所以我們這裡和後面都直接用單位向量來計算,省去不少麻煩。
2.Mathf.Rad2Deg表示的是 單位弧度的度數。也就是2π/360
3.通過叉積計算度數是通過公式|c|=|a||b|sin<a,b>來逆向求值。|c| 其實就是叉積的模,換句話說,也代表著Vector3.Distance (Vector3.zero, Vector3.Cross (a.normalized, b.normalized))的值。
結果圖如下:
點乘與叉乘專案中的應用
專案需求:
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
返回值為正時,目標在自己的右方,反之在自己的左方
相關文章
- Unity向量的演算法:叉乘和叉乘的實戰用法Unity演算法
- 向量點乘為降維,叉乘為升維點乘
- Unity開發中常用的基礎3D數學(向量,點乘,叉乘,矩陣,四元數,尤拉角)Unity3D點乘矩陣
- 【數學】向量點乘、叉乘的理論、應用及程式碼實現(C++)點乘C++
- 點乘和叉乘及其物理意義(C++STL實現)點乘C++
- CUDA版本稀疏矩陣向量乘矩陣
- OpenMP 版本稀疏矩陣向量乘矩陣
- 最小二乘與梯度下降梯度
- 最小二乘(LS)與總體最小二乘(TLS)總結一TLS
- SciTech-BigDataAIML-LLM-Transformer Series-Self-Attention:由Dot-Product(向量點乘)說起AIORM點乘
- 三維旋轉矩陣 左乘和右乘分析矩陣
- 三維空間變換中旋轉矩陣左乘與右乘的區別矩陣
- ECDSA—模乘模組
- 計算階乘
- ACM 階乘之和ACM
- 矩陣連乘矩陣
- CUDA 版本矩陣乘矩陣
- 高精度加減乘
- 大數階乘的AS3與C++版本S3C++
- 乘聯會:2021年11月份全國乘用車市場分析
- 乘聯會:2021年10月份全國乘用車市場分析
- 理解最小二乘解
- 矩陣連乘問題矩陣
- hdu 1757 矩陣連乘矩陣
- Oracle中實現連乘Oracle
- SQL SERVER 求階乘之和SQLServer
- 子陣列的乘積陣列
- 面試題:階乘問題面試題
- 階乘質因數分解
- 卷積運算元的矩陣向量乘積表示&一維離散降質模型卷積矩陣模型
- 乘聯會:2020年11月份全國乘用車市場分析
- 乘聯會:2020年10月份全國乘用車市場分析
- 乘聯會:2022年12月份全國乘用車市場分析
- poj 2778 AC自動機與矩陣連乘矩陣
- 乘聯會:2024年5月份全國乘用車市場分析
- 乘聯會:2024年7月份全國乘用車市場分析
- oracle按列求乘積(轉)Oracle
- 字串相乘——求字串的乘積字串