【unity基础】点乘和叉乘

1、点乘

定义:a*b=|a||b|cos<a,b>

几何意义:一条边向另一条边的投影乘以另一条边的长度

运算:x1*x2+y1*y2+z1*z2.结果是一个标量不是一个变量。

应用:

1、根据点乘计算两个向量的夹角

2、根据点乘的结果得到夹角的大小范围,判断某一个角色是在镜头前还是镜头后。如果点乘结果>0 表示夹角是0-90度,是在镜头前,否则在镜头后。

3、根据点乘的结果判断两个向量的长度大小关系

 

2、叉乘

定义:axb=c,三个都是向量

几何意义:结果是一个于这两个向量都垂直的向量,这个向量的模是以两个向量为边的平行四边形的面积

运算:(y1*z2-y2*z1)*i+(x2*z1-x1*z2)*j+(x1*y1-x2*y1),思考题:如何演算出来的结果?

性质:

1、向量c和ab所在平面垂直

2、|c|=|a||b|*sin<a,b>

3、axb = -bxa,叉乘的的方向右手定则确定。可以用来判断a向量是在b向量的左边或者是右边,或者是顺/逆时针方向

右手定则:右手的四指方向指向第一个矢量,屈向叉乘矢量的夹角方向(两个矢量夹角方向取小于180°的方向),那么此时大拇指方向就是叉乘所得的叉乘矢量的方向.

区别:

1、点乘判断角度,叉乘判断方向

2、得到a,b夹角的正弦值,计算向量的夹角(0,90),可以配合点乘和Angle方法计算出含正负的方向。

3、根据叉乘大小,得到a,b向量所形成的平行四边形的面积大小,根据面积大小得到向量的相对大小。

代码

 //点积
    private void TestDot(Vector3 a, Vector3 b)
    {
        // 计算 a、b 点积结果
        float result = Vector3.Dot(a, b);
 
        // 通过向量直接获取两个向量的夹角(默认为 角度), 此方法范围 [0 - 180]
        float angle = Vector3.Angle(a, b);
 
        // 计算 a、b 单位向量的点积,得到夹角余弦值,|a.normalized|*|b.normalized|=1;
        result = Vector3.Dot(a.normalized, b.normalized);
        // 通过反余弦函数获取 向量 a、b 夹角(默认为 弧度)
        float radians = Mathf.Acos(result);
        // 将弧度转换为 角度
        angle = radians * Mathf.Rad2Deg;
    }
 
    //叉乘
    private void TestCross(Vector3 a, Vector3 b)
    {
        //计算向量 a、b 的叉积,结果为 向量 
        Vector3 c = Vector3.Cross(a, b);
 
        // 通过反正弦函数获取向量 a、b 夹角(默认为弧度)
        float radians = Mathf.Asin(Vector3.Distance(Vector3.zero, Vector3.Cross(a.normalized, b.normalized)));
        float angle = radians * Mathf.Rad2Deg;
 
        // 判断顺时针、逆时针方向,是在 2D 平面内的,所以需指定一个平面,
        //下面以X、Z轴组成的平面为例 , (Y 轴为纵轴),
        // 在 X、Z 轴平面上,判断 b 在 a 的顺时针或者逆时针方向,
        if (c.y > 0)
        {
            // b 在 a 的顺时针方向
        }
        else if (c.y == 0)
        {
            // b 和 a 方向相同(平行)
        }
        else
        {
            // b 在 a 的逆时针方向
        }
    }
 
    // 获取两个向量的夹角  Vector3.Angle 只能返回 [0, 180] 的值
    // 如真实情况下向量 a 到 b 的夹角(80 度)则 b 到 a 的夹角是(-80)
    // 通过 Dot、Cross 结合获取到 a 到 b, b 到 a 的不同夹角
    private void GetAngle(Vector3 a, Vector3 b)
    {
        Vector3 c = Vector3.Cross(a, b);
        float angle = Vector3.Angle(a, b);
 
        // b 到 a 的夹角
        float sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(a.normalized, b.normalized)));
        float signed_angle = angle * sign;
 
        Debug.Log("b -> a :" + signed_angle);
 
        // a 到 b 的夹角
        sign = Mathf.Sign(Vector3.Dot(c.normalized, Vector3.Cross(b.normalized, a.normalized)));
        signed_angle = angle * sign;
 
        Debug.Log("a -> b :" + signed_angle);
    }

https://zhuanlan.zhihu.com/p/89046275