【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

返回值为正时,目标在自己的右方,反之在自己的左方

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity 中,点乘(Dot Product)、叉乘(Cross Product)和投影(Projection)是常用的向量运算。下面我会分别解释它们的含义和用法。 1. 点乘(Dot Product):点乘是两个向量之间的一种运算,结果是一个标量(Scalar)。它可以用来计算两个向量之间的夹角余弦值,还可以判断两个向量是否正交(垂直)或平行。在 Unity 中,可以使用 Vector3.Dot 方法来计算两个三维向量点乘结果。 示例代码: ```csharp Vector3 a = new Vector3(1, 2, 3); Vector3 b = new Vector3(4, 5, 6); float dotProduct = Vector3.Dot(a, b); ``` 2. 叉乘(Cross Product):叉乘是两个向量之间的一种运算,结果是一个新的向量。它的方向垂直于原始两个向量,并符合右手法则。在 Unity 中,可以使用 Vector3.Cross 方法来计算两个三维向量叉乘结果。 示例代码: ```csharp Vector3 a = new Vector3(1, 2, 3); Vector3 b = new Vector3(4, 5, 6); Vector3 crossProduct = Vector3.Cross(a, b); ``` 3. 投影(Projection):投影是将一个向量沿着另一个向量的方向进行投影的过程。投影后的结果是一个新的向量,与原始向量垂直。在 Unity 中,可以使用 Vector3.Project 方法来计算一个三维向量在另一个三维向量上的投影结果。 示例代码: ```csharp Vector3 a = new Vector3(1, 2, 3); Vector3 b = new Vector3(4, 0, 0); Vector3 projectedVector = Vector3.Project(a, b); ``` 以上是在 Unity 中使用点乘叉乘和投影的基本示例。希望对你有所帮助!如果还有其他问题,请继续提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值