如何将世界坐标转换为相机坐标?

22

我有一个输入的三维向量,还有摄像机的俯仰角和偏航角。有没有人能够描述或提供一个资源链接来帮助我理解和实现所需的变换和矩阵映射?

3个回答

27
世界到相机的变换矩阵是相机到世界变换矩阵的反转。相机到世界的变换矩阵是将相机定位移动到指定位置和旋转到指定方向的组合。因此,如果 M 是相机方向对应的3x3旋转矩阵, t 是相机位置,则4x4相机到世界矩阵为:
M00 M01 M02 tx M10 M11 M12 ty M20 M21 M22 tz 0 0 0 1
注意,假设向量为列向量,在右侧乘以执行变换。如果使用相反的约定,请务必转置矩阵。
要查找 M ,可以使用维基百科上列出的公式之一,具体取决于您的滚动、俯仰和偏航公约。请记住,这些公式使用向量为行向量的约定,左乘。
与其计算相机到世界的矩阵并反转它,更有效(以及数值稳定)的替代方法是直接计算世界到相机矩阵。要执行此操作,请反转相机的位置(通过否定所有3个坐标)和其方向(通过否定滚动、俯仰和偏航角,并将其调整到其适当范围内),然后使用相同的算法计算矩阵。

相机到世界矩阵和反之意味着什么?此外,左乘或右乘不清楚是Mv还是vM。 - gmagno
1
@gmagno 相机到世界矩阵将一个点从相机坐标系转换到世界坐标系。我认为通过右乘,Adam 的意思是 $vM^T$,其中 v = [x, y, z, 1] 是相机坐标系中位置的行向量,而 M 是相机到世界矩阵。 - vivkul
1
有人能解释一下如何通过否定翻译坐标来得到与反转矩阵相同的结果吗?我用一个例子尝试了一下,如果你反转和仅仅否定t向量,最后一列并不会保持不变。 - vyb

9
如果我们有这样的结构来描述一个4x4矩阵:
class Matrix4x4
{
public:
    union
    {
        struct
        {
            Type Xx, Xy, Xz, Xw;
            Type Yx, Yy, Yz, Yw;
            Type Zx, Zy, Zz, Zw;
            Type Wx, Wy, Wz, Ww;
        };

        struct
        {
            Vector3<Type> Right;
            Type XW;
            Vector3<Type> Up;
            Type YW;
            Vector3<Type> Look;
            Type ZW;
            Vector3<Type> Pos;
            Type WW;
        };

        Type asDoubleArray[4][4];
        Type asArray[16];
    };
};

如果您只有欧拉角,即代表偏航、俯仰和翻滚的角度以及表示位置的三维空间中的一个点,则可以计算出正确的、向上的和观察向量。请注意,正确的、向上的和观察向量只是X、Y、Z向量,但由于这是相机,我觉得更容易命名为这样。将旋转应用于相机矩阵的最简单方法是构建一系列旋转矩阵,并将我们的相机矩阵与每个旋转矩阵相乘。
这里有一个很好的参考:http://www.euclideanspace.com 在应用所有所需的旋转之后,您可以将矢量Pos设置为相机在世界空间中的位置。
最后,在应用相机变换之前,您需要取相机矩阵的逆。这是您在开始绘制多边形之前将要将模型视图矩阵乘以的内容。对于上面的矩阵类,逆矩阵的计算方法如下:
template <typename Type>
Matrix4x4<Type> Matrix4x4<Type>::OrthoNormalInverse(void)
{
    Matrix4x4<Type> OrthInv;
    OrthInv = Transpose();
    OrthInv.Xw = 0;
    OrthInv.Yw = 0;
    OrthInv.Zw = 0;
    OrthInv.Wx = -(Right*Pos);
    OrthInv.Wy = -(Up*Pos);
    OrthInv.Wz = -(Look*Pos);
    return OrthInv;
}

最终,经过我们所有的矩阵构建,你将会做如下操作:

Matrix4x4<float> cameraMatrix, rollRotation, pitchRotation, yawRotation;
Vector4<float> cameraPosition;

cameraMatrix = cameraMatrix * rollRotation * pitchRotation * yawRotation;

Matrix4x4<float> invCameraMat;

invCameraMat = cameraMatrix.OrthoNormalInverse();

glMultMatrixf(invCameraMat.asArray);

希望这对你有所帮助。

-19
你所描述的是“透视投影”,网络上有大量资源可以解释矩阵数学并提供必要的代码。你可以从wikipedia page开始。

4
透视投影是将3D点投影到2D空间(画布)的一种方法。从世界坐标系到相机坐标系的转换只是将3D点转换为考虑相机变换的3D点。 - Lan Vukušič

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接