如何将本地对象坐标转换为世界坐标?

问题描述:

我需要一种简单的方法将我的对象坐标转换为世界坐标,以便a可以在坐标系中找到它们并进行碰撞检测?如何将本地对象坐标转换为世界坐标?

+0

我建议关于线性代数或马阅读trix代数和一本关于图形的书。 – 2011-05-06 19:49:10

首先,一些背景。在3D图形,你需要担心的几个向量空间:

  • 模型空间 - 这是通常的坐标你指定的OpenGL
  • 世界空间 - 坐标相对于世界上一些中心点指定。
  • 视图空间 - 相对于相机指定坐标
  • 投影空间 - 屏幕上的所有内容适用于每个维度的间隔[-1, +1]

坐标被指定为均匀,所以每个矢量都有组件(x, y, z, w),其中w是比例因子。您可以使用(x/w, y/w, z/w)获得三维坐标。缩放因子对于某些转换(比如透视投影)来说是必需的,而这对于非均匀坐标是不可能的。

需要4x4矩阵来将坐标从一个向量空间转换到另一个向量空间。你可以有三种不同的矩阵:

  • 模型矩阵(模型世界)
  • 查看矩阵(世界查看)
  • 投影矩阵(视图投影空间)

你会项目坐标C在屏幕上使用公式:

C' = P * V * M * C 

OpenGL实习生盟友维护两个矩阵:modelview(模型和视图相乘在一起)和投影。还有一个我们不担心的纹理矩阵。当您拨打glMatrixMode时,您正在切换这些矩阵。用glLoadIdentity替换当前矩阵与单位矩阵。使用glTranslatefglRotatefgluProjection等函数对当前矩阵应用变换。这些函数中的每一个都创建了一个4x4矩阵,实现了特定的变换,然后将当前矩阵乘以它。您可以看到OpenGL 2.1 reference pages中的转换矩阵。


现在为实际的答案。您需要为场景中的每个对象维护一个4x4模型矩阵。模型矩阵将包含将模型坐标转换为世界坐标所需的所有转换。举例来说,每次调用glTranslate时候,你会更新你的模型矩阵:

T = [ 1 0 0 x ] 
    [ 0 1 0 y ] 
    [ 0 0 1 z ] 
    [ 0 0 0 1 ] 
M' = M * T 

然后你可以用你的模型矩阵得到坐标转换成世界空间(确保它们是齐次坐标第一;刚刚成立w = 1,如果他们不是):

V' = V * M 

由于要维持这些并行转换,你实际上并不需要再维持了OpenGL模型视图矩阵。您可以将您的模型矩阵作为统一传递给着色器。您可以用类似的方式维护自己的视图和投影矩阵。这在最新版本的OpenGL中是必需的;所有的矩阵处理函数都被弃用。

+1

我该如何维护我自己的模型矩阵? – 2011-05-06 17:15:55

+0

@Shazad,增加了一些背景信息和更详细的解释。希望有所帮助。 – 2011-05-06 17:48:11

+0

@Jay:首先你说'C'= P * V * M * C',然而,在你说'V'= M * V'的结尾。我有点困惑,因为一旦它是'V * M'并且一次'M * V'。矩阵乘法不可交换,所以'A * B!= B * A'。难道你的答案中的任何一个顺序都是错误的?也许这也是我的数学错误,但在这种情况下,请随时纠正我。 – Mecki 2012-05-21 18:11:30

您可以使用虚拟摄像机视图矩阵(V-1)倍的对象模型视图矩阵(V * M)来获得世界坐标的倒数的产品。

你只是gluLookAt()函数使用后获得五:

glGetFloatv(GL_MODELVIEW_MATRIX,camViewMatrix)

然后反矩阵和存储,(用于乘后面的代码中)。

你在哪里,你要绘制对象点获得V *男,刚过所有的glTranslatef(),glRotatef()和glScale()使用相同的GL功能命令:

glGetFloatv(GL_MODELVIEW_MATRIX,objectsModelVie wMatrix);

V-1 *(V * 中号)== 中号

然后倍数的两个矩阵,生成的基质中包含的位置,M12 = X,M13 = y和M14 = Z

更多细节在与C语言代码: https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/