3D模型使用旋转矩阵实现旋转
最近做一个3d模型的旋转项目,总结下旋转矩阵的原理和应用,直接上效果图,之后讨论原理。
三维空间的旋转(3D Rotation)是一个很神奇的东东:如果对某个刚体在三维空间进行任意次的旋转,只要旋转中心保持不变,无论多少次的旋转都可以用绕三维空间中某一个轴的一次旋转来表示。表示三维空间的旋转有多种互相等价的方式,常见的有旋转矩阵、DCM、旋转向量、四元数、欧拉角等。本篇文章主要梳理一下这些表示方式及相互转换的方法。(自我理解:三维物体在xyz坐标中,绕任意两个轴旋转就可以遍历整个三维物体的任意角落,如:电子设计竞赛的板球控制系统)
一、欧拉角(Euler Angle)
在欧拉角的表示方式里,三个旋转轴一般是随着刚体在运动,即wikipedia中所谓的intrinsic rotation,见下图动画所示(图来自wikipedia)。相对应的另一种表示方式是,三个旋转轴是固定的,不随刚体旋转而旋转,即extrinsic
rotation,这种表示方式在计算机视觉中不是很常用。
注意:绕xyz三轴旋转的顺序不一样,最终的结果也不一样。因此一个三维体经过xyz轴到某一位置,如果想还原之前的位置,则必须按照zyx轴的顺序依次还原。比如,同样的yaw-pitch-roll顺序,(0,90,0)和(90,90,90)会将刚体转到相同的位置。
二、 旋转矩阵(Rotation Matrix)
1.基本原理
旋转矩阵是基于一系列欧拉角方程组提炼出来的系数矩阵(3*3),假设欧拉角yaw、pitch、roll的角度为alpha, beta, gamma,则旋转矩阵可以计算如下:
其中
旋转矩阵可以拆分为绕x,y,z三轴旋转的矩阵之乘积,绕x,y,z轴旋转的顺序取决于子矩阵
乘积的顺序。
2.旋转矩阵实例:
现在实现八边形棱柱体三维旋转控制,三维物体在xyz坐标中,绕任意两个轴旋转就可以遍历整个三维物体的任意角落,因此采用绕x、y两轴旋转即可实现旋转控制。
首先使用数组存储棱柱体的全部线段(两个顶点的坐标),在过将这些坐标先绕x轴旋转度,之后再绕y轴旋转度,在将最新的线段坐标显示出来,即可完成三维体的旋转。
公式如下:
C#代码实现旋转矩阵函数:
public Point transferMatrix(Point p, double beta, double theta)
{
/*
* | x | | cos(beta) -sin(beta) 0 | | cos(theta) 0 -sin(theta) | | x0 |
* | y | = | sin(beta) cos(beta) 0 | * | 0 1 0 | * | y0 | (绕z、y轴旋转)
* | z | | 0 0 1 | | sin(theta) 0 cos(theta) | | z0 |
*/
/*
* | cos(beta) -sin(beta) 0 |
* | sin(beta) cos(beta) 0 | (绕z轴旋转)
* | 0 0 1 |
*/
/*
* | cos(theta) 0 -sin(theta) |
* | 0 1 0 | (绕y轴旋转)
* | sin(theta) 0 cos(theta) |
*/
beta = beta / 180 * Math.PI;
theta = theta / 180 * Math.PI;
double x0 = p.x;
double y0 = p.y;
double z0 = p.z;
//绕x轴旋转beta
double x1 = x0;
double y1 = Math.Cos(beta) * y0 - Math.Sin(beta) * z0;
double z1 = Math.Sin(beta) * y0 + Math.Cos(beta) * z0;
//绕y轴旋转theta
double x2 = Math.Cos(theta) * x1 - Math.Sin(theta) * z1;
double y2 = y1;
double z2 = Math.Sin(theta) * x1 + Math.Cos(theta) * z1;
return new Point(x2,y2,z2);
}
三维旋转效果:
具体的C#源码项目下载地址:https://download.csdn.net/download/qq_37271216/12248409
3D模型是纯代码实现,无需任何外部插件,直接运行可用,里面的矩阵旋转算法简洁可移植性高,适合其他任何高级语言(java、pathon、c++)使用。
有需要代码的朋友,可以将邮箱留下,免费发送到邮箱。
上一篇: QT5.11下载与安装教程