Unity 点乘和叉乘的原理和使用

Unity当中经常会用到向量的运算来计算目标的方位,朝向,角度等相关数据,下面咱们来通过实例学习下Unity当中最常用的点乘和叉乘的使用。

点乘

(又称"点积","数量积”,"内积")(Dot Product, 用*)
定义:a·b=|a|·|b|cos<a,b> 【注:粗体小写字母表示向量,<a,b>表示向量a,b的夹角,取值范围为[0,180]】
几何意义:是一条边向另一条边的投影乘以另一条边的长度.

v1和v2向量的点乘运算:相应元素的乘积的和:v1( x1, y1,z1) * v2(x2, y2,z2) = x1x2 + y1y2+z1z2;
注意 : 结果不是一个向量,而是一个标量。
性质1: a
b = |a||b|Cos(θ) ,θ是向量a 和向量 b之间的夹角。
性质2: ab = ba 满足乘法交换律
Unity项目应用:
1.根据点乘计算两个向量的夹角。<a,b>= arccos(a·b / (|a|·|b|))
2.根据点乘的正负值,得到夹角大小范围,>0,则夹角(0,90)<0,则夹角(90,180),可以利用这点判断一个多边形是面向摄像机还是背向摄像机。
3.根据点乘的大小,得到向量的投影长度,反应了向量的长度关系。
4.在生产生活中,点积同样应用广泛。利用点积可判断一个多边形是否面向摄像机还是背向摄像机。向量的点积与它们夹角的余弦成正比,因此在聚光灯的效果计算中,可以根据点积来得到光照效果,如果点积越大,说明夹角越小,则物理离光照的轴线越近,光照越强。物理中,点积可以用来计算合力和功。若b为单位矢量,则点积即为a在方向b的投影,即给出了力在这个方向上的分解。功即是力和位移的点积。计算机图形学常用来进行方向性判断,如两矢量点积大于0,则它们的方向朝向相近;如果小于0,则方向相反。矢量内积是人工智能领域中的神经网络技术的数学基础之一,此方法还被用于动画渲染(Animation-Rendering)。

叉乘

(又称"叉积","向量积","外积")(cross product,用x)
定义:c = a x b,其中a b c均为向量
几何意义是:得到一个与这两个向量都垂直的向量,这个向量的模是以两个向量为边的平行四边形的面积
v1和v2向量的叉乘运算:相应元素的乘积的和:v1( x1, y1,z1) x v2(x2, y2, z2) = (y1z2 - y2z1)i+(x2z1 - x1z2)j+(x1y2-x2y1)k;
利用三阶行列式计算
|i j k|
|x1 y1 z1|
|x2 y2 z2|
性质1:c⊥a,c⊥b,即向量c与向量a,b所在平面垂直
性质2:模长|c| = |a||b| sin<a,b>
性质3:(数学上)满足右手法则, a x b = -b x a,所以我们可以使用叉乘的正负值来判断a,b的相对位置,即b是处于a的顺时针还是逆时针方向。
叉乘的右手定则是用来确定叉乘积的方向的。
右手法则:右手的四指方向指向第一个矢量,屈向叉乘矢量的夹角方向(两个矢量夹角方向取小于180°的方向),那么此时大拇指方向就是叉乘所得的叉乘矢量的方向.(大拇指应与食指成九十度)(注意:Unity当中使用左手,因为Unity使用的是左手坐标系)

数学上叉乘的右手法则

Unity当中叉乘的左手法则

Unity项目应用:
1.根据叉乘得到a,b向量的相对位置,和顺时针或逆时针方位。
简单的说: 点乘判断角度,叉乘判断方向。
形象的说: 当一个敌人在你身后的时候,叉乘可以判断你是往左转还是往右转更好的转向敌人,点乘得到你当前的面朝向的方向和你到敌人的方向的所成的角度大小。
2.得到a,b夹角的正弦值,计算向量的夹角(0,90),可以配合点乘和Angle方法计算出含正负的方向。
3.根据叉乘大小,得到a,b向量所形成的平行四边形的面积大小,根据面积大小得到向量的相对大小。

下面是代码

using UnityEngine;  
  
public class VectorExample : MonoBehaviour {  
  
    //点积  
    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);  
    }  
}  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容