一种摄像机锁定的实现方法(原创)
By 头发抽筋
摄像机的锁定的功能在3D游戏里面经常用到,摄像机有时候必须跟着某个目标移动,或者以固定轨道的方式来观察摄像机锁定的物体,这会遇到一些问题,下面具体描述了我用球体的参数方程来实现一个摄像机的锁定功能。
摄像机锁定一个目标的时候,往往是根据摄像机和目标的位置,然后计算摄像机的向量来对准目标。这样有个问题,就是想改变摄像机和目标的相对位置时会很麻烦,需要输入摄像机的新坐标,如果只想使摄像机相对目标围绕纵轴旋转90°,你会发现这样做会很麻烦,下面只是介绍一下实现的思路,
被锁定的物体你可以想象成是球体的中心点,然后摄像机在球体上运动,并且一直在对准球体的中心,这样,根据球体的参数方程:
x=r * sin(α) * cos(β)
y=r * sin(α) * sin(β)
z=r * cos(α)
(这里z轴是纵轴, y轴指向右方, x轴指向垂直于纸面的方向)r是球的半径,α角是半径与Z轴正向的夹角,β角是半径在xy平面的投影与x轴正向的夹角,他们的取值范围是 0≤ r ≤ ∞, 0≤ α ≤ π, 0 ≤ β ≤ 2π。
你只要为你摄像机锁定的函数提供3个参数:距离(球体半径)r,两个夹角参数α, β,就可以方便的控制摄像机移动到几乎相对于被锁定物体的任意位置,下面提供OpenGL实现的部分代码。
// x, y, z 是摄像机的位置,alpha,beta就是公式中的α,β
// dst 是公式中的半径r
{
// 放置beta和alpha为90的倍数
if ( int ((beta / 90 )) % 2 != 0 )
beta ++ ;
if ( int ((alpha / 90 )) % 2 != 0 )
alpha ++ ;
// 这里值得注意,OpenGL的坐标系是x轴向右,y轴向上,z轴向前
// 在赋值的时候需要交换公式中的坐标轴,需要做的变换如下:
// Zogl = X公式
// Xogl = Y公式
// Yogl = Z公式
// degrees2radians() 函数是我自己定义的角度转弧度,C库函数sin() 和cos()的参数
// 是弧度
x = dst * sin (degrees2radians (alpha)) * sin (degrees2radians (beta)) ;
y = dst * cos (degrees2radians (alpha));
z = dst * sin (degrees2radians (alpha)) * cos (degrees2radians (beta)) ;
}
void Camera::lockOn (GLfloat alpha, GLfloat beta, GLfloat dst)
//x, y, z 是摄像机的位置,alpha,beta就是公式中的α,β
//dst 是公式中的半径r
{
//放置beta和alpha为90的倍数
if(int((beta / 90)) % 2 != 0)
beta ++;
if(int((alpha / 90)) % 2 != 0)
alpha ++;
//这里值得注意,OpenGL的坐标系是x轴向右,y轴向上,z轴向前
//在赋值的时候需要交换公式中的坐标轴,需要做的变换如下:
//Zogl = X公式
//Xogl = Y公式
//Yogl = Z公式
//degrees2radians() 函数是我自己定义的角度转弧度,C库函数sin() 和cos()的参数
//是弧度
x = dst * sin (degrees2radians (alpha)) * sin (degrees2radians (beta)) ;
y = dst * cos (degrees2radians (alpha));
z = dst * sin (degrees2radians (alpha)) * cos (degrees2radians (beta)) ;
用此方法稍加改动还可以绘制线框球体。