作业要求
完善以下函数:
get_model_matrix(float rotation_angle): 逐个元素地构建模型变换矩阵并返回该矩阵。在此函数中,你只需要实现三维中绕 z 轴旋转的变换矩阵,而不用处理平移与缩放。
get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar): 使用给定的参数逐个元素地构建透视投影矩阵并返回该矩阵。
在 main.cpp 中构造一个函数,该函数的作用是得到绕任意过原点的轴的旋转变换矩阵。
Eigen::Matrix4f get_rotation(Vector3f axis, float angle)作业实现
旋转矩阵
绕 z 轴旋转的变换矩阵,只需写出旋转矩阵即可:
Eigen::Matrix4f get_model_matrix(float rotation_angle) {
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
model << cos(rotation_angle / 180 * MY_PI), -sin(rotation_angle / 180 * MY_PI), 0, 0,
sin(rotation_angle / 180 * MY_PI), cos(rotation_angle / 180 * MY_PI), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
return model;
}透视投影矩阵
-
先计算各个参数
const auto t = zNear * tan(eye_fov / 2 / 180 * MY_PI); const auto r = t * aspect_ratio; const auto l = -r; const auto b = -t; const auto f = -zFar; const auto n = -zNear; -
再构造正交投影矩阵
ortho_trans << 1, 0, 0, -(r + l) / 2, 0, 1, 0, -(t + b) / 2, 0, 0, 1, -(n + f) / 2, 0, 0, 0, 1; ortho_scale << 2 / (r - l), 0, 0, 0, 0, 2 / (t - b), 0, 0, 0, 0, 2 / (n - f), 0, 0, 0, 0, 1; ortho = ortho_scale * ortho_trans; -
将正交投影矩阵转换为透视投影矩阵
persp_to_ortho << n, 0, 0, 0, 0, n, 0, 0, 0, 0, f + f, -n * f, 0, 0, 1, 0; projection = ortho * persp_to_ortho;
任意轴旋转矩阵
使用 Rodrigues’ rotation formula:
其中 是轴向量, 是旋转角度, 是单位矩阵。
Eigen::Matrix4f get_rotation(Vector3f axis, float angle) {
Eigen::Matrix4f rotation = Eigen::Matrix4f::Identity();
//Rodrigues’ Rotation Formula
Eigen::Matrix3f N;
N << 0, -axis.z(), axis.y(),
axis.z(), 0, -axis.x(),
-axis.y(), axis.x(), 0;
rotation.block<3, 3>(0, 0) = Eigen::Matrix3f::Identity() * cos(angle) + (1 - cos(angle)) * axis * axis.transpose() + sin(angle) * N;
return rotation;
}