點乘:兩個向量點乘獲得一個標量 ,數值等於兩個向量長度相乘後再乘以兩者夾角的餘弦值 。若是兩個向量a,b均 爲單位 向量 ,那麼a.b等於向量b在向量a方向上的投影的長度函數
點乘後獲得的是一個值this
若結果 == o,則 兩向量 互垂直 。
若結果 < 0 ,則 兩向量夾角大於90°。
若結果 >0 ,則兩向量夾角小於 90°。.net
叉乘:兩 個向量的叉乘獲得一個新的向量 ,新向量垂直於原來的兩個向量再乘夾角的正弦值 3d
叉乘後獲得的仍是一個向量code
在Unity3D裏面。兩個向量的點乘所獲得的是兩個向量的餘弦值,也就是-1 到1之間,0表示垂直,-1表示相反,1表示相同方向。 兩orm
個向量的叉乘所獲得的是兩個向量所組成的面的垂直向量,分兩個方向。 簡單的說,點乘判斷角度,叉乘判斷方向。 形象的說當一個get
敵人在你身後的時候,叉乘能夠判斷你是往左轉仍是往右轉更好的轉向敵人,點乘獲得你當前的面朝向的方向和你到敵人的方向的所數學
成的角度大小。string
爲了理解以上問題咱們先了解一下Sin和Cos兩個數學函數;it
一、Sin和Cos的基礎知識:
Sin函數:
取值範圍是-1到1.
注意:
sin(0) = 0;
sin(90) = 1;
sin(180) = 0;
sin(270) = -1;
sin(360) = 0;
由此咱們獲得 0--180 爲正數,180--360取負數;
度數如爲負數,則與之相反以下:
sin(0) = 0;
sin(-90) = -1;
sin(-180) = 0;
sin(-270) = 1;
sin(-360) = 0;
Cos函數:
取值範圍是-1到1.
注意:
cos(0) = 1;
cos(90) = 0;
cos(180) = -1;
cos(270) = 0;
cos(360) = 1;
由此咱們獲得 0--90,270 -- 360 爲正數,90 --270取負數;
度數如爲負數,與之相同以下:
cos(0) = 1;
cos(-90) = 0;
cos(-180) = -1;
cos(-270) = 0;
cos(-360) = 1;
二、在瞭解sin和cos的基礎知識後,咱們來看一下叉乘和點乘的公式;
以上咱們瞭解,點乘的結果是一個浮點數
點乘公式:
|a|*|b| * cos<a,b>
向量a、b的大小和a、b之間的cos夾角相乘。
題一:player是一個玩家,判斷Enemy在player的前方或後方。
player的前方咱們設爲a向量,Enemy到player的向量咱們設爲b向量 ,因此Enemy所在先後取決於Cos夾角,若是Cos夾角得出是正數,則在前方。如爲負數,則在後方。代碼以下:
float dot(Vector3 a,Vector3 b) { return Vector3.Dot(a,b); } void main() { float tmp = dot(a,b); if(tmp > 0) { Debug.Log("b在a的前方"); }else if(tmp < 0) { Debug.Log("b在a的後方"); } else { Debug.Log("b在a的正左側或正右側"); } }
題二:player是一個玩家,判斷Enemy在player的哪一個方位。
public class DotAndCross : MonoBehaviour { public Transform obj; // Use this for initialization void Start () { } float timer = 0f; float devTimer = 2f; // Update is called once per frame void Update () { if ((timer + devTimer) > Time.time) return; timer = Time.time; Vector3 tmpDir = obj.position - transform.position; Debug.Log("cross == " + cross(transform.forward, tmpDir.normalized)); } /// <summary> /// 判斷方位 /// </summary> /// <param name="dirOne"></param> /// <param name="dirTwo"></param> /// <returns></returns> string JudgeDirection(Vector3 dirOne,Vector3 dirTwo) { Vector3 tmpRightOrLeft = cross(dirOne, dirTwo); float tmpForwardOrBehind = dot(dirOne, dirTwo); if (tmpRightOrLeft.y > 0 && tmpForwardOrBehind > 0) { return "敵人在玩家的右前方"; } else if (tmpRightOrLeft.y > 0 && tmpForwardOrBehind < 0) { return "敵人在玩家的右後方"; } else if(tmpRightOrLeft.y < 0 && tmpForwardOrBehind > 0) { return "敵人在玩家的左前方"; } else if(tmpRightOrLeft.y < 0 && tmpForwardOrBehind < 0) { return "敵人在玩家的左後方"; } else if (tmpRightOrLeft.y == 0 && tmpForwardOrBehind > 0) { return "敵人在玩家的正前方"; } else if (tmpRightOrLeft.y == 0 && tmpForwardOrBehind < 0) { return "敵人在玩家的正後方"; } else if (tmpRightOrLeft.y > 0 && tmpForwardOrBehind == 0) { return "敵人在玩家的正右方"; } else if (tmpRightOrLeft.y < 0 && tmpForwardOrBehind == 0) { return "敵人在玩家的正左方"; } else { return "玩家和敵人重合"; } } float dot(Vector3 objOne,Vector3 objTwo) { return Vector3.Dot(objOne,objTwo); } Vector3 cross(Vector3 objOne, Vector3 objTwo) { return Vector3.Cross(objOne,objTwo); }