unity3d四元数和旋转矩阵

一 四元数


Quaternion中存放了x,y,z,w四个数据成员,可以用下标来进行访问,对应的下标分别是0,1,2,3。


主要介绍几个函数


<1> 根据两个向量计算出旋转量,计算出来的旋转量为从fromDirection旋转到toDirection的旋转量

static Quaternion FromToRotation(Vector3 fromDirection,Vector3 toDirection);


<2>

static Quaternion LookRotation(Vector3 forward);
static Quaternion LookRotation(Vector3 forward,Vector3 upwards);

使用指定的向前方向和向上方向来创建四元数


示例

Vector3 vr = new Vector3(1,0,0);
Quaternion q1 = Quaternion.LookRotation(vr);
Debug.Log(q1);
		
Vector3 vforwardp = new Vector3(0,0,1);		
Quaternion q2 = Quaternion.FromToRotation(vforwardp ,vr);
Debug.Log(q2);


这里面q1和q2的值是相同的,q2的计算过程是计算向前向量(vforwardp )到当前向量vr的旋转量,而这就是LookRotation的计算方式

而是LookRotation同时使用forward和upward两个参数的时候,就相当于指定了vz和vy两个向量,根据这两个向量可以直接算出对应的vx,然后再用这三个向量去set对应的3×3旋转矩阵的列向量即可获得一个旋转矩阵,再接着可以将其转换到四元数。


<3>

void SetLookRotation(Vector3 view);
void SetLookRotation(Vector3 view,Vector3 up);

也是根据指定的向前和向上向量创建四元数,本质计算过程和LookRotation一样,只不过LookRotation是Quaternion上的静态函数,而SetLookRotation则是Quaternion的成员函数。


<4>

static Quaternion RotateTowards(Quaternion from,Quaternion to, float maxDegreesDelta);

以maxDegreesDelta作为角度步长计算从from到to之间的旋转量


<5>

static Quaternion AngleAxis(float angle,Vector3 axis);

根据旋转轴和旋转角度算出四元数


<6>Quaternion.eulerAngles

存放四元数对应的三个轴向的欧拉角,分别是绕x轴、y轴、z轴旋转的角度


Quaternion q3 = new Quaternion();
q3.eulerAngles = new Vector3(10, 30, 20);
Quaternion qx3 = Quaternion.AngleAxis(10,Vector3.right);		
Quaternion qy3 = Quaternion.AngleAxis(30,Vector3.up);
Quaternion qz3 = Quaternion.AngleAxis(20,Vector3.forward);
		
Quaternion qxyz3 = qz3*qy3*qx3;


上面的代码可以得到q3和qxyz3值一样。 从这里可以看出unity中旋转顺序也是按先绕x轴旋转,然后y,最后z 。unity中对向量应用旋转量使用的是向量右乘,即如下:

Vector3 newV = qxyz3*v=qz3*qy3*qx3*v;

二 旋转矩阵

unity中仅仅提供了一个4×4的矩阵类Matrix4x4,它可以包含位移T、旋转R和伸缩信息。矩阵中的元素都对应一个mxy的公有成员变量,因而要访问单个元素的话可以直接访问其成员。同时也提供了下标访问,如下

public float this [int row, int column]
{
    get
    {
	    return this [row + column * 4];
    }
    set
    {
	    this [row + column * 4] = value;
    }
}
public float this [int index]

三 四元数和旋转矩阵之间的转换

unity中没有提供直接的四元数到旋转矩阵的转换,但是使用它们的一些成员函数可以实现两者之间的转换。

1 四元数到旋转矩阵

使用Matrix4x4的成员函数SetTRS

void SetTRS(Vector3 pos,Quaternion q,Vector3 s);


示例

Quaternion q = Quaternion.LookRotation(new Vector3(0,0.5,1));
Matrix4x4 rot = new Matrix4x4();
rot.SetTRS(new Vector3(0,0,0),q,new Vector3(1,1,1));


2 旋转矩阵到四元数

使用Quaternion类的LookRotation函数

static Quaternion LookRotation(Vector3 forward,Vector3 upwards);


示例(接上面):

Matrix4x4 rot = new Matrix4x4();
rot.SetTRS(new Vector3(0,0,0),q,new Vector3(1,1,1));
		
Vector4 vy = rot.GetColumn(1);
Vector4 vz = rot.GetColumn(2);
		
Quaternion newQ = Quaternion.LookRotation(new Vector3(vz.x,vz.y,vz.z),new Vector3(vy.x,vy.y,vy.z));

这里的newQ与上面的q等值

四 其他

unity中可以将一个四元数q换算到一个旋转矩阵R,同时将这个q在Ogre中换算到另一个旋转矩阵R1,发现R和R1是相同的。


这说明虽然unity和Ogre采用的是不同的坐标系,但是对于四元数和旋转矩阵之间的换算是等价的。同时unity中四元数的计算公式也和《三维旋转基础》中的一样。




  • 14
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Unity中,四元数(Quaternion)是一种用于表示旋转的数据类型。它由四个实数构成,即(x, y, z, w),其中前三个分量表示旋转轴的向量部分,而第四个分量表示旋转角度的标量部分。 Unity使用四元数来表示物体的旋转是因为它具有很多优点,例如避免万向节锁(Gimbal Lock)问题以及提供更高效的旋转计算。使用四元数可以执行平滑的插值和旋转操作,并且在进行多个旋转操作时不会出现旋转误差的累积问题。 在Unity中,可以通过Quaternion类来创建和操作四元数。你可以使用Quaternion.Euler函数通过欧拉角(Euler angles)来创建一个四元数,也可以使用Quaternion.LookRotation函数通过指定的方向向量来创建一个四元数。此外,你还可以使用四元数的乘法运算来执行旋转的组合操作。 例如,要将一个物体绕着Y轴旋转90度,可以使用以下代码: ```csharp Quaternion rotation = Quaternion.Euler(0f, 90f, 0f); transform.rotation = rotation; ``` 这将把物体的旋转设置为绕着世界坐标系的Y轴旋转90度。 需要注意的是,Unity中的四元数是归一化的,即它们的长度(模)始终为1。因此,如果你直接修改四元数的值,可能会导致旋转失效或产生意想不到的结果。通常情况下,建议使用旋转操作函数(如Rotate、RotateAround等)来进行旋转操作,而不是直接修改四元数的值。 总而言之,四元数Unity中一种用于表示旋转的强大数据类型,它提供了灵活而高效的旋转操作,使你可以在游戏开发中实现各种复杂的旋转效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值