向量点乘和叉乘在Unity中的应用

文章介绍了如何通过向量的点乘和叉乘来确定它们之间的方位关系,例如在Unity中,可以利用这些运算来判断玩家相对于其他物体的位置,如左前、右后等。此外,还提到了四元数与欧拉角在旋转向量中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义:

1.点乘:向量a在向量b上的投影长度*b的模长
a⋅b=|a||b|θ*cosθ
a⋅b=|a|cosθ*|b|
|a|cosθ是a投影在b上的长度,再乘|b|就是点乘结果了
结果:dot>0 同向;dot<0 反向;dot==0 垂直
疑问:如果只是确定方位,为什么要用点乘,直接|a|*cosθ不可以吗
原因:点乘还有另一条公式 a·b=x1x2+y1y2+z1z2 这条公式天然的将长度和角度计算在一起而不用考虑两者之间的夹角,而|a|*cosθ需要计算夹角和模长
总结:点乘其实并不需要理解数值大小代表了什么,只需要考虑dot>0,dot<0表示什么就可以了

实例

1.向量的点乘和叉乘可以获取方位

以前的项目有遇到过这种情况:需要知道玩家相对于另一个物体的方位。
对向量a和向量b分别做叉乘和点乘,得到如下结果:
a.通过叉乘的左手法则我们可以知道:
叉乘y值>0的时候,a在b的左边;
叉乘y值<0的时候,a在b的右边
b.通过点乘我们可以知道:
当点乘>0的时候,两个向量所成的夹角<90,为锐角,a在b的前面;
当点乘<0的时候,两个向量所成的夹角>90,为钝角,a在b的后面
两者结合,就可以获取两个向量的前后左右方位了,具体应用如下

public class VectorTest : MonoBehaviour
{
    public Transform player;	//玩家
    public Transform cube;	//其他物体
    public Text txt;

    private void Update()
    {
        Vector3 playerForward = player.forward; //玩家看向方向
        Vector3 playerToCube = cube.position - player.position; //player->cube 向量
        Debug.DrawLine(Vector3.zero, playerForward, Color.green);
        Debug.DrawLine(Vector3.zero, playerToCube, Color.red);
        Vector3 cross = Vector3.Cross(playerToCube, playerForward); //确定左右
        float dot = Vector3.Dot(playerToCube, playerForward);   //确定前后

        //cube在玩家的左边
        if(cross.y > 0)
        {
            //cube在玩家的前面
            if(dot > 0)
            {
                txt.text = "cube在玩家的左前方";
            }
            else if(dot < 0)
            {
                txt.text = "cube在玩家的左后方";
            }
            else
            {
                txt.text = "cube在玩家的正左方";
            }
        }
        //右边
        else if(cross.y < 0)
        {
            //cube在玩家的前面
            if (dot > 0)
            {
                txt.text = "cube在玩家的右前方";
            }
            else if (dot < 0)
            {
                txt.text = "cube在玩家的右后方";
            }
            else
            {
                txt.text = "cube在玩家的正右方";
            }
        }
        else  //cross.y==0的情况,说明两个向量的z轴都为0,应该看cross.z,如果cross.z也为0的情况,则看cross.x
        {
            txt.text = "无法判断";
        }
    }
}

上面的代码可以获取玩家和物体的方位,首先根据叉乘获取左右方向,之后再根据点乘获取前后方向。
在这里插入图片描述

其实判断方位有另一种办法,只需要靠点乘就可以,但是前提是需要知道一个物体b的forawrd向量和right向量。先用物体a.position-b.position,得出一个向量p,由p与b.forward做点乘dot
dot>0,a在b的前方;
dot<0,a在b的后方
再与b.right做点乘dot
dot>0,a在b的右方;
dot<0,a在b的左方
通过与两个方向做点乘,就可以知道前后左右的方位了

Unity中四元数与欧拉角相乘

Quaternion * Vector3 表示一个Vector3方向向量经过Quaternion四元数转换后得到的新的方向向量
于是可以得到下面的一个函数

	//旋转一个方向向量
    //direction 方向向量
    //euler 欧拉角
    public static Vector3 Rotate(Vector3 direction, Vector3 euler)
    {
        //将一个方向向量旋转euler度
        Vector3 newVector = Quaternion.Euler(euler) * direction; 
        return newVector;
    }
    
	 //将一个欧拉角转换为方向向量
    public static Vector3 EulerToDirection(Vector3 euler)
    {
    	//必须用Vector3.forward,这样旋转得到的方向向量才是正确的
       Vector3 newVector = Quaternion.Euler(euler) * Vector3.forward;
        return newVector;
    }

点乘与法向量,平面的关系

我们知道一个法向量n,那么法向量和这个平面的点乘即为0(90度)
有一点p在平面上方,平面中的一点t,则有下面的结论:
如果(p-t)·n>0,则表示p在平面上方(正面) ;
如果(p-t)·n<0,则表示p在平面下方(反面),如图2
在这里插入图片描述
[图2]

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、付费专栏及课程。

余额充值