<style type="text/css">
<!--
@page
{margin:2cm}
pre
{font-family:"DejaVu Sans Mono",monospace}
p.我的格式-western
{font-family:"DejaVu Sans",sans-serif;
font-size:10pt}
p.我的格式-cjk
{font-size:10pt}
p.我的格式-ctl
{font-size:12pt}
p
{margin-bottom:0.21cm}
-->
</style>
用OpenGL制作摄像机系统
花了我很长的时间,才把这个摄像机系统制作出来。主要是因为要做这个摄像机系统,就要学习很多的数学知识。没有这些数学知识,想在三维中驰骋是很难的。这里最让我头疼的就是已知一个三维向量,求它相对一个向量旋转后的向量。我找了很多资料,终于在一篇网站上找到了。上面写着可以使用四元组的方法,也可以使用旋转矩阵的方法。其中四元组的方法由于我的理解有限,就没有做出来。所以借着《OpenGL超级宝典》和东拼西凑的一些知识,我完成了旋转矩阵的计算。做了一个小实验,结果还挺准确的呢。
演示程序下载地址:这里
程序源代码下载地址:这里
这里先看一下我的截图吧。
图1从下往上看
图2从上往下看
这里看一下别人是如何描述问题并且解决问题的:
3D空间中的旋转可用旋转矩阵、欧拉角或四元数等形式来表示,他们不过都是数学工具,其中在绕任意向量的旋转方面,旋转矩阵和四元数两种工具用的较多,欧拉角由于存在万向节死锁等问题,使用存在限制。
(本文假设坐标系为左手坐标系中,旋转方向为顺时针。)
所求问题:
给定任意单位轴q(q1,q2,q3)(向量),求向量p(x,y,z)(或点p)饶q旋转theta角度的变换后的新向量p'(或点p'):
1.用四元数工具:
-------------------------------------------------------------------------
结论:构造四元数变换p'=q*p*q-1,(p,q是由向量p,q扩展成的四元数)。那么,p'转换至对应的向量(或点)就是变换后的新向量p'(或点p')。
其中,p',q,p,q-1均为四元数。q由向量q扩展,为q=(cos(theta/2),sin(theta/2)*q),p由向量p扩展,为p=(0,x,y,z),q-1为q的逆,因为q为单位四元数,所以q-1=q*=(cos(theta/2),-sin(theta/2)*q)。
-------------------------------------------------------------------------
(这个结论的证明过程可以在网上找到。这里略去。)
下面看其时间复杂度:
首先有个三角函数的计算时间,这个可以预先计算好,花费时间不计。考虑n个四元数相乘需进行4*4*(n-1)=16*(n-1)次乘法,15*(n-1)次加法,因为加法化费时间较少,这里仅考虑乘法。这里涉及到三个四元数的乘法,设一次乘法的时间为T,故花费16*2=32T
2.旋转矩阵工具:
-------------------------------------------------------------------------
结论:构造旋转矩阵变换Trot,则变换后的新向量p'(或点p')为p'=p*Trot
其中,p'(x',y',z',1),p(x,y,z,1)为向量p',p的4D齐次坐标表示,Trot=
|t*q1*q1 + c,t*q1*q2 + s*q3, t*q1*q3 -s*q2, 0|
|t*xq1*q2 -s*q3, t*q2*q2 + c,t*q2*q3 + s*q1, 0|
|t*q1*q3 +s*q2, t*q2*q3 - s*q1,t*q3*q3 + c,0|
|0,0,0,1|
c=cos(theta),s=sin(theta),t=1-c.
-------------------------------------------------------------------------
(这个结论的证明过程可以在网上找到。这里略去。)
下面看其时间复杂度:
三角函数的计算时间不计。矩阵本身的元素乘法主要是计算t*x和s*x之类,需进行12+3=15次乘法。两个矩阵相乘的需进行n*n*n次乘法,这里n=4,所以花费4*4*4=64次乘法时间,但这里有个注意的地方就是旋转矩阵的第4维无须考虑,即可简化为3X3的矩阵。故花费3*3*3=27次乘法时间,总共的时间为15+27=42次乘法时间。cost=42T.
比较来看,还是使用四元数的效率要高出一些,这在要变换的点的数目越大时,体现的越明显。实际上,有很多3D引擎为了利用四元数运算的高效率性,一般先将矩阵转换成四元数后进行运算再转回为矩阵后,再传给DirectX或OpenGL库函数。
有谁能够了解四元数能解决这个问题的?先谢谢了!
没有办法,我还是研究旋转矩阵的方法吧。上面介绍中,q1、q2、q3分别代表轴向量的x、y和z坐标。根据下列公式进行演算就可以得出旋转矩阵。恰好OpenGL有一个载入矩阵的好方法:glMultMatrixf(matrix
);,用它可以载入任何4✕4的矩阵。这样计算再结合《OpenGL超级宝典》,得出来的代码就像这样:
float* RotationMatrix( float* pOutMatrix, const Vector3F& vector,
float angleInRadius )// 使用矩阵的方法计算矩阵(也可以使用四元组,但是我不会……)
{
// 确保pOutMatrix是一个矩阵
assert( pOutMatrix != 0 );
float c = cos( angleInRadius ), s = sin( angleInRadius ), t = 1.0f - c;
float txx = t * vector.x * vector.x,
txy = t * vector.x * vector.y,
txz = t * vector.x * vector.z,
tyy = t * vector.y * vector.y,
tyz = t * vector.y * vector.z,
tzz = t * vector.z * vector.z,
sx = s * vector.x,
sy = s * vector.y,
sz = s * vector.z;
#define MATRIX( row, col ) pOutMatrix[ row * 4 + col ]// 临时定义的宏
MATRIX( 0, 0 ) = txx + c;
MATRIX( 0, 1 ) = txy + sz;
MATRIX( 0, 2 ) = txz - sy;
MATRIX( 0, 3 ) = 0.0f;
MATRIX( 1, 0 ) = txy - sz;
MATRIX( 1, 1 ) = tyy + c;
MATRIX( 1, 2 ) = tyz + sx;
MATRIX( 1, 3 ) = 0.0f;
MATRIX( 2, 0 ) = txz + sy;
MATRIX( 2, 1 ) = tyz - sx;
MATRIX( 2, 2 ) = tzz + c;
MATRIX( 2, 3 ) = 0.0f;
MATRIX( 3, 0 ) = 0.0f;
MATRIX( 3, 1 ) = 0.0f;
MATRIX( 3, 2 ) = 0.0f;
MATRIX( 3, 3 ) = 1.0f;
#undef MATRIX
return pOutMatrix;
}
分享到:
相关推荐
Qt+OpenGL摄像机,移动,放大缩小,Qt+OpenGL摄像机,移动,放大缩小,Qt+OpenGL摄像机,移动,放大缩小,Qt+OpenGL摄像机,移动,放大缩小,Qt+OpenGL摄像机,移动,放大缩小,Qt+OpenGL摄像机,移动,放大缩小,Qt...
适合初学者学习opengl,使用opengl实现摄像机漫游功能,
一个关于opengl摄像机移动的demo.......................................
C++ OpenGL 简单FPS摄像机系统
花了我很长的时间,在把这个摄像机系统制作出来。主要是因为要做这个摄像机系统,就要学习很多的数学知识。没有这些数学知识,想在三维中驰骋是很难的。这里最让我头疼的就是已知一个三维向量,求它相对一个向量旋转...
OpenGL 摄像机初始化与摄像机键盘控制
花了我很长的时间,在把这个摄像机系统制作出来。主要是因为要做这个摄像机系统,就要学习很多的数学知识。没有这些数学知识,想在三维中驰骋是很难的。这里最让我头疼的就是已知一个三维向量,求它相对一个向量旋转...
OpenGL 制作的旋转飞机 可以作为大作业
OpenGL+VS2015,在3D的空间内可以向各个方向移动摄像机的角度,通过wasd控制
w,s,a,d分别摄像机为向前后左右移动,键盘的上下左右为镜头所观察方向的上下左右移动
opengl 摄像机围绕目标转动。fps风格相机。
图形加速编程(OPENGL)摄像机方面例子 1:w,e,q,a,s,d,均可易用来控制圆柱的平移 达到装配的功能 2:上,下,左,右,end建用于控制立方体的平移; 3:鼠标在左键的按下状态下,拖动可以实现从不同角度观察 4:...
opengl 环境下的摄像机漫游 c++ vc6.0
此源码实现基于OpenGL的摄像漫游,OpenGL入门程序之摄像机操作,主要介绍摄像机的移动方法及实现-OpenGL
对学习openg 3D很有帮助的哦,欢迎下载
OpenGL制作的三维场景,包括一些二维与三维的点状线状符号算法,可以进行漫游浏览
用opengl制作一个简单的界面。对于建立其他应用是比较实用的程序,对初学者比较有用!
利用opengl和vs2005制作的一个简单的粒子系统
用opengl做的一个雷霆战机的小游戏,适合初学者参考。
opengl实现uvn摄像机 pitch yaw roll 应用简单glsl 如无法运行请添加库 http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/SIXTH_EDITION/CODE/include/