📜  3d 投影到 2d 平面算法 - C++ (1)

📅  最后修改于: 2023-12-03 14:59:05.057000             🧑  作者: Mango

3D 投影到 2D 平面算法 - C++

在计算机图形学中,将三维立体物体投影到二维平面上是一个重要的问题。本文介绍一种常用的 3D 投影到 2D 平面的算法。

步骤
1. 投影平面的选择

首先需要选择投影平面,通常选择的平面是垂直于视线方向的平面。我们可以通过将视点看作是在投影平面的另一侧,从而使得投影方向垂直于投影平面。在本文中,我们选择的投影平面为 XY 平面,视线方向为 Z 轴正方向。

2. 计算投影矩阵

将三维坐标 (x, y, z) 投影到二维坐标 (x', y'),需要进行以下变换:

  • 将 (x, y, z) 坐标系旋转,使得 Z 轴与投影方向重合,这里采用欧拉角旋转矩阵来实现:
// 欧拉角旋转矩阵
glm::mat4 rotationMatrix = glm::yawPitchRoll(yaw, pitch, roll);
  • 将坐标系平移,使得原点位于投影平面上:
// 平移矩阵
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -distance));
  • 将模型矩阵,投影矩阵和视图矩阵相乘,得到最终的投影矩阵:
// 模型矩阵、视图矩阵和投影矩阵
glm::mat4 modelMatrix = glm::mat4(1.0f);
glm::mat4 viewMatrix = glm::lookAt(eye, center, up);
glm::mat4 projectionMatrix = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
glm::mat4 projectMatrix = projectionMatrix * viewMatrix * modelMatrix;
3. 投影变换

对于每个三维坐标点 (x, y, z),通过将其与投影矩阵相乘,将其投影到二维坐标 (x', y') 上:

glm::vec4 position(x, y, z, 1.0f);
position = projectMatrix * position;
position /= position.w;
float x’ = position.x;
float y’ = position.y;

其中,position.w 表示投影后的坐标点的深度值,我们需要将其除以其自身以归一化深度值。

完整代码
glm::mat4 rotationMatrix = glm::yawPitchRoll(yaw, pitch, roll);
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -distance));
glm::mat4 modelMatrix = glm::mat4(1.0f);
glm::mat4 viewMatrix = glm::lookAt(eye, center, up);
glm::mat4 projectionMatrix = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
glm::mat4 projectMatrix = projectionMatrix * viewMatrix * modelMatrix;

for (size_t i = 0; i < vertices.size(); i++)
{
    glm::vec4 position(vertices[i].x, vertices[i].y, vertices[i].z, 1.0f);
    position = projectMatrix * position;
    position /= position.w;
    vertices[i].x = position.x;
    vertices[i].y = position.y;
}
结论

通过本文介绍的算法,我们可以将三维立体物体投影到二维平面上,实现立体物体的渲染和显示。