将投影矩阵44分解为左,右,底,顶,近和远边界值

时间:2012-05-31 08:52:23

标签: android opengl-es qcar-sdk

任何人都可以帮我从投影矩阵44获得左,右,底,顶,近和远边界值?

3 个答案:

答案 0 :(得分:9)

以下是等式系统Christian Rau的分辨率:

对于正交矩阵:

near   =  (1+m34)/m33;
far    = -(1-m34)/m33;
bottom =  (1-m24)/m22;
top    = -(1+m24)/m22;
left   = -(1+m14)/m11;
right  =  (1-m14)/m11;

对于透视矩阵:

near   = m34/(m33-1);
far    = m34/(m33+1);
bottom = near * (m23-1)/m22;
top    = near * (m23+1)/m22;
left   = near * (m13-1)/m11;
right  = near * (m13+1)/m11;

您可以使用glOrthoglFrustum文档中定义的公式替换值m11,m12等,以检查它是否正确。

答案 1 :(得分:2)

首先,您可以查看如何为glOrthoglFrustum(或您框架中的类似函数)的相应调用定义这些矩阵。接下来的步骤取决于投影的类型,可以是正交的(例如来自glOrtho)或透视(例如来自glFrustumgluPerspective),这可以通过查看第3列来确定

现在对于正交矩阵来说,很容易找到两个方程式:

right - left = 2 / m11
right + left = -2 * m14 / m11

通过这些,您可以非常轻松地计算right = (1-m14) / m11left = right - 2/m11(您可以重新检查我的精神算术期间发生的任何错误)。和其他两对参数相似(注意m33)的符号。

对于透视投影,您应首先使用nearfar计算m33m34。然后,您可以计算right/leftbottom/top,类似于上述情况,但使用计算的near值。

总而言之,一旦你根据参数知道了矩阵的公式,它实际上归结为一堆简单的2x2方程系统很容易解决。一个更有趣的问题是,为什么你真的需要从投影矩阵计算这些参数。如果你真的需要它们,你应该只存储它们(因为你是构建矩阵的人,无论如何)。否则,它听起来像是使用OpenGL进行更多事情(比如场景管理)的另一个实例,而不仅仅是一个简单的绘图API。

答案 2 :(得分:1)

为了将来参考,我在这里复制C ++ for OpenGL中具有0索引的列主投影矩阵的近,远等值:

float near = m_projectionMatrix[3][2] / (m_projectionMatrix[2][2] - 1.0f);
float far = m_projectionMatrix[3][2] / (m_projectionMatrix[2][2] + 1.0f);
logStderr(VERBOSE, "near, far %5.2f, %5.2f...\n", near, far);

float nearBottom = near * (m_projectionMatrix[2][1] - 1) / m_projectionMatrix[1][1];
float nearTop = near * (m_projectionMatrix[2][1] + 1) / m_projectionMatrix[1][1];
float nearLeft = near * (m_projectionMatrix[2][0] - 1) / m_projectionMatrix[0][0];
float nearRight = near * (m_projectionMatrix[2][0] + 1) / m_projectionMatrix[0][0];
logStderr(VERBOSE, "nearLeft, nearRight, nearTop, nearBottom %5.2f, %5.2f, %5.2f, %5.2f...\n", nearLeft, nearRight, nearTop, nearBottom);

float farBottom = far * (m_projectionMatrix[2][1] - 1) / m_projectionMatrix[1][1];
float farTop = far * (m_projectionMatrix[2][1] + 1) / m_projectionMatrix[1][1];
float farLeft = far * (m_projectionMatrix[2][0] - 1) / m_projectionMatrix[0][0];
float farRight = far * (m_projectionMatrix[2][0] + 1) / m_projectionMatrix[0][0];
logStderr(VERBOSE, "farLeft, farRight, farTop, farBottom %5.2f, %5.2f, %5.2f, %5.2f...\n", farLeft, farRight, farTop, farBottom);