您的位置:首页 > 移动开发 > Unity3D

自己用的unity学习笔记(一)——数学相关

2017-12-21 18:27 260 查看

数学相关

Quaternion四元数   eulerAngles
欧拉角

Random.Range();unity自带的随机数

数学函数库

float rad = deg * Mathf.Deg2Rad; 度到弧度的转化

向量

既有大小又有方向的箭头。

三角函数

情景,三角形,a,b,c

Sin正弦,sinθ = b/c;
对边比斜边

正弦规律:

Sin0 = 0,sin90 = 1;sin180=0;sin-90 = -1;sin-180 = 0;

Cos余弦, cosθ = a/c;
临边比斜边

余弦曲线:

 

Tan正切  tanθ = b/a;
对边比临边

正切曲线:

 

Costan余切 costanθ = a/b;临边比对边

 

向量点乘

点乘:. 表示,点乘结果可以求得两个向量的相似度,也就是两个向量的夹角。

夹角一定是内角,不可能大于180.

夹角一般称为θ,西塔

A(ax,ay,az)  B(bx,by,bz)

A点乘B = ax*bx+ay*by+az*bz = |a|*|b|*cos<A,B>

Unity Vector3.Dot(a,b);点乘算法

向量的大小,也就是向量的长度(或称模)。向量a的模记作|a|

注:1.向量的模是非负实数,是可以比较大小的。

几何意义:a向量在b向量上的投影长度,再乘以b向量的模。如果ab都为单位向量,所以结果就是cosθ。如果b向量是单位向量,得到的是a向量在b向量上的投影。

Vectors.ProjectOnPlane(投影向量,法线);  计算一个向量在平面上的投影。

 

如何把一个向量变成单位向量:每一个向量除以向量的模。Unity中使用 向量.Normalize()或向量.normalized(参考向量归一化)

情景:如果cosθ大于0,证明θ为锐角,否则是钝角(原理参照余弦曲线),如果以目标物体正前方向量和目标物体到跟随物体的向量模拟三角形的两边,夹角锐角证明跟随物体在目标物体前方,钝角则在目标物体后方。

如果点乘为1,两个向量相似。

点乘为0,夹角为90度,为垂直向量。

点乘为-1,夹角180度,两个向量相反

Acos()可以求得cosθ(单位向量的点乘)的弧度,如果想得到角度,还需要乘以mathf.Rad2Deg,转化成角度

如果只是想算向量夹角,只需要使用vector3.Angle(向量1,向量2)上述内容都不需要用。

点乘可以计算赏金猎人的大招范围

向量叉乘

叉乘:X 表示,叉乘结果表示法线,法线垂直于a向量,b向量。

A(ax,ay,az)  B(bx,by,bz)

计算原则:计算谁的值,就将谁的值挡住

AXB =(ay*bz-az*by, az*bx- ax*bz,ax*by-ay*bx) = |a|*|b|*sin<A,B>

 

Unity Vector3.cross(v1,v2);

 

Y轴又称法向量(法线),法线垂直于切线。

情景:

(目标物体前方X跟随物体向量)

目标物体的前方向量和目标物体到跟随物体(跟随物体-目标物体)的叉乘,如果为负数(法线朝下),可以表示该跟随物体在目标物体的左面,正数(法线朝上)在右面。

向量相加:

几何意义是得到三角形第三边的向量

一个坐标点加一个向量,得到的是一个新的坐标点,即坐标点沿着向量方向移动向量长度,例如transform.position+vector3.up

向量减法:

得出夹角的对边的向量。

箭头指向是被减数,比如a-b,箭头指向a,b-a箭头指向b

向量归一化

即是向量的模

模长计算 |A| = 开方(x平方+y平方)

不开方叫平方模长,可以节省计算。

根号2  1.414

根号3  1.732

根号5  2.236

向量归一化后,长度为1(坐标根号2/2,根号2/2),方向不变。

Unity中向量的归一化使用 向量.Normalize()或向量.normalized

向量.Normalize()
没有返回值,直接修改向量本身。

向量.normalized
是属性, 不修改本身,返回向量归一化的值。

向量乘以标量

乘以正数几何意义是对向量的缩放

乘以负数,则是反转方向,并缩放

向量插值

Vector3.lerp(from,to,百分比);

插值百分比使用1/剩余百分比,可实现匀速移动。

Quaternion四元数

旋转使用,由实数和虚数组成,是一个超复数,一个实数三个虚数组成。例如:2+3i+4k+5g.

实数:有理数(整数和分数的集合)和无理数(无限不循环的小数)的集合叫实数

虚数:想象不到的数,比如:根号-1 = I;

复数:由实部和虚部的组成,例如2+3i就是一个复数。

虚数运算法则(实际上也是复数的运算):

(a+bi)+(c+di) = (a+c)+(b+d)i

(a+bi)-(c+di) = (a-c)+(b-d)i

(a+bi)*(c+di) = (a*c – b*d)+(a*d+b*c)i

 

四元数是一个超复数,一个实数三个虚数组成,unity中有四个分量x,y,z,w,x,y,z全是虚数,w为实数。

四元数中存储的是轴角对,就是绕一个轴(n(x,y,z))转多少度(θ)角。

X = n.x*sin(θ/2); Y = n.y*sin(θ/2); Z = n.z*sin(θ/2); W = cos(θ/2);

四元素不能加,只能乘,乘相当于加。

四元数一次只能旋转一个轴,不能一次性转多个角度,而且四元数旋转的轴有固定顺序,y轴-x轴-z轴,否则得到结果不一样。

四元数多用于计算,欧拉角多用于直接赋值。

优缺点

优点:

1、 不存在万向死锁

2、 计算精确

3、 可以进行平滑插值(例如相机平滑的旋转,应该使用四元数)

缺点:

4、 单个的四元数不能表示在任何方向上超过180度的旋转。

5、 四元数的数字不直观,计算麻烦,只能一根一根轴旋转

6、 存储空间大,比欧拉角多33%,

四元数函数

Quaternion.lookrotation(向量方向);
将目标方向向量转换成四元数的旋转值。

具体使用:例如转向目标方向(可以用lookat但,lookat无法使用插值平滑),用目标位置减去当前位置,获得对应的向量方向,lookrotation就能将对应向量转化成四元数旋转值,rotation就可以直接获取。

Quaternion.AngleAxis (角,轴);将轴角对的旋转变成四元数。该函数可以相乘,例如:Quaternion.AngleAxis (角,轴)*
Quaternion.AngleAxis (角,轴)。效果就是旋转量的叠加。

Transform.eulerAngles;属性,可赋值可获取

Quaternion.identity 无旋转。等同欧拉角的vector3.zero;

四元数可以直接转欧拉角,用四元数.eulerAngles

 

旋转插值

Quaternion.Slerp();球形插值,插值百分比使用1/剩余角度,可实现匀速旋转。

四元数的计算

四元数的模:

根号(x^2+y^2+z^2+w^2)

四元数的乘法:

把xyz看成一个向量v,w看做标量

【v1,w1】*【v2,w2】
= [w1*v2+w2*v1+v2叉乘v1,w1*w2-v1点乘v2]

四元数的共轭:

就是把四元数虚数部分取负数,实数部分不变,就是原四元数的共轭四元数。

如果用一个四元数来表示按照n轴旋转θ度,那共轭就是绕着n轴反向旋转θ度。

四元数的逆:

(q代表原四元数)q^-1,共轭四元数除以四元数的模,就是四元数的逆。原四元数和四元数的逆相乘结果是单位四元数。

单位四元数:

(0,0,0,1)[0,1]表示无旋转.在unity中自身无旋转下的坐标轴和世界坐标轴完全重合

四元数乘以Vector3:

必须四元数乘以v3,顺序不能错。

先把vector3变成四元数
= new quaternion(v3.x,v3.y,v3.z,0);

四元数 Newp = q*p*q^-1(q:四元数,p:变成四元数的点)

在unity中已经重载了乘号运算符,可以直接用四元数乘以vector3;

几何意义:如果v3是点,绕着v3点旋转多少度。如果v3是向量,就是原向量按照四元数的旋转一定角度后的新向量。

坐标系转换

想要将物体转到谁的坐标系中,就用谁的实例来调用坐标转换函数。

世界坐标系:原点在世界坐标原点,三根轴是世界坐标系的三根轴。

自身坐标系:原点自身的中心点,三根轴是以自身的前方为z轴,上方为y轴,右方为x轴。

transform.TransformPoint (v3自身点);自身点坐标转世界点坐标

transform.InverseTransformPoint(v3世界);把世界e点坐标转成自身点坐标系。

transform.TransformDirction(v3自身);把向量的方向从自身转到世界坐标系中,只考虑方向,不考虑大小。

transform.InverseTransformDirction(v3世界);世界转自身

世界坐标转换屏幕坐标

屏幕坐标系,原点在屏幕左下角,右上角是屏幕宽高的像素。

分辨率:像素点的多少,横着1024个像素点,竖着768个。

Input.mousePosition 屏幕坐标,v3类型的,但z轴为距离相机的深度值(裁面)

Screen.Width,screen.height  屏幕的宽高

主摄像机默认不用获取组件,使用Camera.main访问。

Camera.main,ScreenToWorldPoint(v3类型)获取屏幕上的点在世界中的位置。V3的z不能为0,z值是距离相机的深度值(裁面),返回值世界坐标的v3。例如:Camera.main,ScreenToWorldPoint(new
vector3(0,0,10)).

Camera.main, WorldToScreenPoint ().

 

eulerAngles 欧拉角

旋转使用

欧拉角是按照一定顺序旋转的角度,按轴转

例如:transform.eulerAngles = new vector3(1,1,1);

该旋转是先按x轴转1,再往Y轴转1,再往z轴转1

容易产生万向死锁,两个轴转成同心。

欧拉角特点:

1、 三个角度组成,比较直观,容易理解。存储简单

2、 可以进行从一个方向到另一个方向旋转大于180的角度

3、 固定的坐标轴旋转(跟旋转顺序有关系)

4、 运算速度比较快,但不精确

5、 会出现万向死锁的问题。(缺点)

6、 由于存在万向死锁欧拉角旋转无法实现球面平滑插值。(缺点)

矩阵

矩阵乘法

(x,y)*(n,m)

矩阵相乘,y必须等于n,最后结果是一个x行m列的矩阵

2行2列
* 2行2列
= 2行2列

1行2列*2行1列
= 1行1列

4行3列* 2行1列
=不能相乘,因为y和n不等,3!=2

4行1列*2行1列
= 4行1列

1,2    2,4        1*2+2*1(1矩阵第一行交叉相乘2矩阵的第一列)1*4+2*0(1第一行交叉乘以2第二列)

3,1    1,0    ==  3*2+1*1 (同类,换成第二行)   3*4+1*0

m00 m01     n00 n01    m00*n00+m01*n10    m00*n01+m01*n11

m10 m11  *  n10 n11  = m10*n00+m11*n10    m10*n01+m11*n11

几何上来说每个行乘以列都是一个向量的点乘,两个矩阵相乘,得出来的就是由点乘组成的新矩阵

3,2 * 1,4  =  7(3*1+2*2),22(3*4+2*5)

2,5   如果没有第二行,就不乘,但列必须有,不然没法相乘,所以y要等于n。

单位矩阵

单位矩阵(E矩阵):反斜杠\对角线方向元素都为1,其他都为0

例如:1,0               1,0,0

      0,1               0,1,0

                        0,0,1

特点:任何其他矩阵乘以单位矩阵,都是它自己

转置矩阵

转置矩阵(T矩阵):第一行变第一列,第二行变第二列

A矩阵,转置矩阵就是AT。

1,0     1,1      1,0

1,0  T  0,0  T   1,0

转置矩阵再转置,就是原矩阵,
所以A和AT互为转置矩阵

矩阵在坐标系转换中的应用

 

矩阵旋转

一个矩阵可以表示一个空间。

优点:

1、 旋转轴可以是任意方向。

缺点:

一般旋转其实只需要知道一个向量Vector3加一个角度,一个四个值,矩阵却需要16个元素,而且在做乘法操作的时候也会增加计算量,造成空间和时间上的一些浪费。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity unity3d