587 字
3 分钟
GAMES101 作业1: 旋转与投影

get_model_matrix(float rotation_angle): 逐个元素地构建模型变换矩 阵并返回该矩阵。在此函数中,你只需要实现三维中绕z轴旋转的变换矩阵, 而不用处理平移与缩放

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
// TODO: Implement this function
// Create the model matrix for rotating the triangle around the Z axis.
// Then return it.
float angle = rotation_angle / 180.0 * MY_PI;
model(0, 0) = std::cos(angle);
model(0, 1) = -std::sin(angle);
model(1, 0) = std::sin(angle);
model(1, 1) = std::cos(angle);
return model;
}

get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar): 使用给定的参数逐个元素地构建透视投影矩阵并返回 该矩阵

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
// Students will implement this function
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it.
Eigen::Matrix4f prespToortho = Eigen::Matrix4f::Identity();
Eigen::Matrix4f ortho = Eigen::Matrix4f::Identity();
Eigen::Matrix4f translate = Eigen::Matrix4f::Identity();
Eigen::Matrix4f scale = Eigen::Matrix4f::Identity();
float t = std::tan(eye_fov / 180.0 * MY_PI / 2) * zNear;
float b = -t;
float r = t * aspect_ratio;
float l = -r;
translate(0, 3) = -(r + l) / 2;
translate(1, 3) = -(t + b) / 2;
translate(2, 3) = -(zNear + zFar) / 2;
scale(0, 0) = 2 / (r - l);
scale(1, 1) = 2 / (t - b);
scale(2, 2) = 2 / (zNear - zFar);
ortho = scale * translate;
prespToortho(0, 0) = zNear;
prespToortho(1, 1) = zNear;
prespToortho(2, 2) = zNear + zFar;
prespToortho(2, 3) = -zNear * zFar;
prespToortho(3, 2) = 1;
prespToortho(3, 3) = 0;
projection = ortho * prespToortho;
return projection;
}

在 main.cpp 中构造一个函数,该函数的作用是得到绕任意 过原点的轴的旋转变换矩阵。 Eigen::Matrix4f get_rotation(Vector3f axis, float angle)

Eigen::Matrix4f get_rotation(Eigen::Vector3f axis, float angle) {
// 最终要返回的 4x4 齐次矩阵,先初始化为单位矩阵
Eigen::Matrix4f rotation = Eigen::Matrix4f::Identity();
// 1. 角度转弧度 (假设输入的 angle 是角度)
// 注意:如果你的环境中没有 MY_PI,可以使用 std::acos(-1.0f) 代替
float rad = angle / 180.0f * MY_PI;
// 2. 将旋转轴标准化为单位向量 (非常重要!公式的前提是单位向量)
Eigen::Vector3f n = axis.normalized();
// 3. 构建 3x3 单位矩阵 I
Eigen::Matrix3f I = Eigen::Matrix3f::Identity();
// 4. 构建叉积矩阵 (反对称矩阵) N
Eigen::Matrix3f N;
N << 0, -n.z(), n.y(),
n.z(), 0, -n.x(),
-n.y(), n.x(), 0;
// 5. 应用罗德里格斯公式计算 3x3 旋转矩阵 R
// n * n.transpose() 就是向量的外积 n * n^T
Eigen::Matrix3f R = std::cos(rad) * I +
(1.0f - std::cos(rad)) * n * n.transpose() +
std::sin(rad) * N;
// 6. 将 3x3 的旋转矩阵填入 4x4 矩阵的左上角
// Eigen 提供了便捷的方法 topLeftCorner 或者 block
rotation.topLeftCorner<3, 3>() = R;
return rotation;
}
GAMES101 作业1: 旋转与投影
https://dingfengbo.vercel.app/posts/games101/assignment-1/
作者
Eureka
发布于
2026-03-25
许可协议
CC BY-NC-SA 4.0