当前位置:   article > 正文

Unity3D 数学知识 (向量,坐标系转换,欧拉角,四元数)_unity有极点、四元数算出直角坐标系

unity有极点、四元数算出直角坐标系

向量:

Unity中Vector3 既能表示坐标点又能表示向量。

向量的概念:有大小有方向的箭头叫向量,没有位置。

坐标点的相减得到一个向量,由减数指向被减数的。

A到B的方向=B(被减数)-A(减数)

B到A的方向=A(被减数)-B(减数)

 

零向量:(0,0,0)     //没有方向

负向量:让原向量乘以-1得到了相当于原向量来说的负向量

 

单位向量:长度为1的向量叫单位向量(1,1,1)        //各个分量分别除以magnitude模长就等于单位向量

     计算公式: Vector v1= new Vector(2,2,3);

     v1= new Vector(v1.x/v1.magnitude,v1.y/v1.magnitude,v1.z/v1.magnitude); //单位化向量之后

     Unity API: Vector.normalized

 


 

向量的模(向量的长度):

    计算公式:向量的长度=sqr(x^2+y^2+z^2) //各向量的平方相加,再开方。

     Unity API: Vector.magnitude

向量相加:

     计算公式:a向量+b向量=c向量      a(x,y,z)+b(x,y,z)=c(ax+bx,ay+by,az+bz)   //各分量分别相加

     几何意义:两个向量相加得到新的向量

 

向量相减:

      计算公式:a向量-b向量=c向量      a(x,y,z)-b(x,y,z)=c(ax-bx,ay-by,az-bz)   //各分量分别相减

      几何意义:两个向量相减得到新的向量。a向量-b向量,得到一个新的向量,从b向量的终点指向a向量的终点。


 

 

向量的乘法:

点乘:

     计算公式:a(ax,ay,az) b(bx,by,bz)

     a点乘b=ax乘bx+ay乘by+az乘bz =|a||b|cos<a,b>(a的模乘b的模,再乘以两个向量夹角的余弦值cosΘ)

     Unity API:Vector.Dot(a,b);      //a b向量点乘

     几何意义:a向量在b向量方向上投影的长度。

     变种1:如果b向量为单位向量,意义为a向量在b向量方向上投影的长度

     变种2:如果a向量和b向量都为单位向量,意义为a向量和b向量夹角的余弦值。

 

叉乘:

     计算公式:a(x1,y1,z1) 叉乘 b(x2,y2,z2)=(y1*z2-z1*y2, z1*x2-x1*z2, x1*y2-y1*x2 ) //交叉相乘再相减

     Unity API:Vector.Cross(A,B);    //a b向量叉乘

     几何意义:两个向量叉乘,得到的结果也是一个向量,结果的向量同事垂直于a b向量,也就是说垂直于 a b向量所在的平面。

 

图示: a向量为红线,b蓝线,黄线是a叉乘b之后得到的向量

 

 a向量为红线,b蓝线,黄线是b叉乘 a之后得到的向量

 

 

坐标系转换:

世界坐标转换为屏幕坐标

Unity API:Camera.main.WorldToScreenPoint(Vector3 position);

如图所示:

世界坐标转换为屏幕坐标,z轴为10,而不是0。屏幕坐标只有x,y轴,而没有z轴。

这里面的z轴就是相机与需要转换的坐标点也就是WorldToScreenPoint(Vector3 position),这个API中的括号内的Vector3 position参数的景深,深度,不是距离。

 

把Cube当做坐标点,转换成屏幕坐标

 

Cube位置偏移之后,z轴还是10,如果是距离,这个时候应该比10大。

 

 

相对坐标

相对于某一个物体的局部坐标(某个物体的子节点)

Unity API :Vector3.InverseTransformPoint(transform.position);

从世界空间到局部空间的位置转换

 

 

 

 

如图所示:

Cube 相对于Sphere的局部坐标

Sphere.InverseTransformPoint(Cube.position);

 

 

Cube挂载到Sphere的子节点,位置对比

 

 

 

游戏物体的旋转在3D引擎中,有三种方式:1、欧拉角 2、四元数 3、矩阵

 

欧拉角:

Unity API:Transform.eulerAngles=new Vector3(0,45,0); //绕着y轴旋转45度

欧拉角,x轴旋转正负90度就会发生万向节死锁

 

x轴旋转90之后,旋转y轴,实际上旋转的是z轴。

 

 

 

四元数:

概念:用四维空间表示三维中的旋转,它有四个分量x,y,z,w

w+ax+by+cz

x^2=y^2=z^2=-1

超复数:一个实部w,三个虚部x,y,z

 

复数:由实部和虚部组成的数  3(实数)+4i(虚数)

实数 :有理数和无理数的集合

有理数:有限小数,无限循环小数,和整数,都叫做有理数(有道理的数)

无理数: e π

i^2=-1   //任何数的平方都不等于-1,这是i就叫做 虚数单位

虚数的例子:5i(前提是i^2=-1),那么5i就是虚数

虚数部分为0,复数就变成了实数

 

四元数存储的是轴角对(一个轴,一个角,绕着某个轴旋转多少度角)

计算公式:

n(nx,ny,nz) //绕着哪个轴   thetaΘ

x=nx*Sin(theta/2);

y=ny*Sin(theta/2);

z=nz*Sin(theta/2);

w=Cos(theta/2);

 

绕着y轴(0,1,0)旋转90度

//===用公式计算=====

//Unity API , Mathf.Sin(float f),Mathf.Cos(float f)传的是一个弧度,Mathf.Deg2Rad把角度转换成弧度

Quaternion q = new Quaternion(0, Mathf.Sin(45 * Mathf.Deg2Rad), 0, Mathf.Cos(45 * Mathf.Deg2Rad));    //90 / 2(theta / 2) == 45;

transform.rotation = q;      //打印出来的q值(0,0.7,0,0.7)

 

//===欧拉角转换成四元数===

Quaternion q = Quaternion.Euler(0, 90,0);       //打印出来的q值(0,0.7,0,0.7)

//===AngleAxis===

Quaternion q = Quaternion.AngleAxis(45, Vector3.up); //绕着y轴旋转45度

transform.rotation = q* q; //四元数相乘,得到旋转量的叠加(90度)

四元数的乘法:代表旋转量的叠加

 

四元数的模: l=sqrt(x^2+y^2+z^2+w^2);    //各分量的平方相加再开方

单位四元数:(0,0,0,1)代表无旋转

共轭四元数:代表和原四元数方向相反的旋转

四元数的转置:原四元数的共轭四元数/四元数的模(在标准四元数中,四元数的转置==四元数的共轭)

标准四元数:模长为1的四元数就叫标准四元数(表示旋转的四元数一定是标准四元数)

单位四元数一定是标准四元数,标准四元数不一定是单位四元数

 

四元数和欧拉角的对比:

四元数:

优点: 1、没有方向锁

2、可以绕着任意轴转

缺点:1、同一时间只能绕着一根轴转

2、难理解

3、多个分量,多占内存

 

欧拉角:

优点:1、容易理解

2、省内存

3、可以三根轴一起旋转

缺点:1、有万向锁

 

数据来源:ABOUTCG网站https://www.aboutcg.org/courseDetails/494/introduce

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/100176
推荐阅读
相关标签
  

闽ICP备14008679号