世界坐标系到相机坐标的变化是个不容易理解的地方。在学习OpenGL的过程中也经常遇到不理解转换矩阵意义的地方。这篇博文讲的还是不错的,遗憾的是,不知道最终来源是哪里。在此记录一下,以便查阅。
世界坐标系到相机坐标系的变换
glm:LookAt 函数的解释
已知,在XYZ坐标系下,有点
。又知道一组新的坐标X'Y'Z',其基向量在 XYZ 坐标系下的表示分别为:
\vec{u}=(u_x,u_y,u_z), \vec{v}=(v_x,v_y,v_z), \vec{w}=(w_x,w_y,w_z)
(注意,这些都是单位向量,这很重要)。令XYZ坐标系的原点为
\vec{O}=(O_x,O_y,O_z)
,X'Y'Z'坐标系的原点为
\vec{O'}=(O'_x,O'_y,O'_z)
。
问题是,点
在 X'Y'Z' 坐标系中的坐标是多少?
解: 首先,在 XYZ 坐标系下,将 X'Y'Z' 的基向量、点 P 同时平移,使
得 X'Y'Z' 的原点 O' 和 点 O 重合。其结果如图所示。
达到这一目的的平移矩阵为:
\begin{pmatrix} 1 & 0 & 0 & -O'_x\ 0 & 1 & 0 & -O'_y\ 0 & 0 & 1 & -O'_z\ 0 & 0 & 0 & 1 \end{pmatrix}
值得注意的是,这样做之后,点在 X'Y'Z' 坐标系中的坐
标并没有改变。因为,我们对其基向量、点 P 同时进行了平移。之后,我们需要一个旋转矩阵,来求得。
关键就在于下面的观察:由图1可以看到,
P'_y=\vec{v}*\vec{OP}
,其中
\vec{v}=(v_x,v_y,v_z),\vec{OP}=(P_x,P_y,P_z)
,所以 Py′ 即可求得。同理,可求得 Px′ , Pz′。
写成矩阵形式:
\begin{pmatrix} P'_x\ P'_y\ P'_z \end{pmatrix} = \begin{pmatrix} \vec{u}\ \vec{v}\ \vec{w} \end{pmatrix} * \vec{OP} = \begin{pmatrix} u_x & u_y & u_z\ v_x & v_y & v_z\ w_x & w_y & w_z \end{pmatrix} * \begin{pmatrix} P_x\ P_y\ P_z \end{pmatrix}
于是,R 的齐次坐标的形式是:
R = \begin{pmatrix} u_x & u_y & u_z &0 \ v_x & v_y & v_z &0 \ w_x & w_y & w_z &0 \ 0 & 0 & 0 &1 \end{pmatrix}
综上,对于一个点
P(P_x,P_y,P_z)
,它在以
\vec{O'}=(O'_x,O'_y,O'_z)
为原点的
X'Y'Z' 坐标系下的坐标
P'=(P'_x,P'_y,P'_z)
为:
\begin{pmatrix} P'_x\ P'_y\ P'_z\ 1 \end{pmatrix} = \begin{pmatrix} u_x & u_y & u_z &0 \ v_x & v_y & v_z &0 \ w_x & w_y & w_z &0 \ 0 &0 &0 & 1 \end{pmatrix} * \begin{pmatrix} 1 & 0 & 0 & -O'_x\ 0 & 1 & 0 & -O'_y\ 0 & 0 & 1 & -O_z\ 0 & 0 & 0 & 1 \end{pmatrix} * \begin{pmatrix} P_x\ P_y\ P_z\ 1 \end{pmatrix}