點乘和叉乘在3D中的實際用法

點乘:兩個向量點乘獲得一個標量 ,數值等於兩個向量長度相乘後再乘以兩者夾角的餘弦值 。若是兩個向量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);
    }
相關文章
相關標籤/搜索