OpenGL实例教程13:摄像机旋转
目标:通过启用鼠标方向控制来完成摄像机的实现。
能够将相机旋转360度(围绕正Y轴),这对应于向左或向右旋转。(轴是确定的)
能够向上或向下倾斜摄像机。(轴是不确定的,实现相对困难)

实现方式:跟随鼠标的移动,当鼠标左右移动时改变水平角度,当鼠标上下移动时改变垂直角度。通过这两个角度,计算目标和向上的向量。
下边是二战高射炮,与我们将要建造的摄像机类似:

旋转可以采用欧拉角(易懂)或四元数(难懂,但容易实现)表示。通过使用四个数来表示方位。可以避免万向节死锁这样的问题。
四元数(基于复数系统):

归一化四元数于归一化向量类似。这里将介绍使用四元数围绕任意向量旋转所需的步骤。计算四元数` W `的通用函数是:

` a `表示旋转角度,` V `被旋转的向量(顶点位置),其中Q为旋转四元数,定义为:

计算` W `后,旋转后的向量就是(W.x,W.y,W.z)。
计算水平旋转:

目标向量是(x,z)。圆的半径长度为1,alpha的正弦函数正好是z。因此,计算z的反正弦函数将得到alpha。z在范围[-1,1]内,asine的结果是-90度到+90度。但是水平角度的范围是0-360度。此外,四元数是顺时针旋转的。当用四元数旋转90度时,最终在Z轴上得到-1,与实际的正弦90度(即1)相反。
最简单的方法是始终使用Z的正值来计算asine函数,并将结果与矢量所在的圆的特定四分之一相结合。例如,当我们的目标向量是(0,1)时,我们计算asine(1),即90,然后用360减去它。结果是270。0到1的正弦范围是0到90度。把它和圆的四分之一结合起来,就得到了最终的水平角度。
计算垂直旋转:
计算垂直角比较简单,将移动范围限制在-90度(等于270度——直视上方)到+90度(直视下方)。这意味着只需要目标向量中Y分量的asine函数的负值。当Y = 1时(向上看)正弦等于90所以我们只需要反转符号。当Y = -1时(垂直向下)正弦值是-90而倒过来是90。
计算四元数的数学库:
Camera库中的相关实现:
(camera.cpp)
应用程序实现代码: