文章目录
基础
Model transform
绕着 Z Z Z 轴旋转,直接带入四元数公式(多加上一维,不要平移变换):
代码
Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
float ra = rotation_angle / 180.0f * MY_PI;
Eigen::Matrix4f rotate_z;
rotate_z <<
std::cos(ra), -std::sin(ra), 0, 0,
std::sin(ra), std::cos(ra), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
return rotate_z * model;
}
Perspective projection
由于关于 x − y − p l a n e x-y-plane x−y−plane 对称,所以可以将 M p e r M_{per} Mper 由:
根据实际绘图可知:
改写为:
代码
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
float Y = eye_fov / 180.0f * MY_PI;
float Y_over_2 = Y * 0.5f;
float cot_Y_over_2 = 1.0f / tan(Y_over_2);
Eigen::Matrix4f perspective_p;
perspective_p <<
-cot_Y_over_2 / aspect_ratio, 0, 0, 0,
0, -cot_Y_over_2, 0, 0,
0, 0, (zFar + zNear) / (zNear - zFar), 2.0f * zFar * zNear / (zFar - zNear),
0, 0, 1, 0;
return perspective_p * projection;
}
效果
提高
Rotation
根据 R o d i g u e s ′ R o t a t i o n F o r m u l a Rodigues' Rotation Formula Rodigues′RotationFormula,直接套公式就行。
代码
Eigen::Matrix4f get_rotation(Vector3f axis, float angle)
{
Eigen::Matrix3f I = Eigen::Matrix3f::Identity(); // N is 3f
Eigen::Vector3f nl = axis.normalized(); // normal line
float ra = angle / 180.0f * MY_PI;
Eigen::Matrix4f rotate_any_axis = Eigen::Matrix4f::Zero();
rotate_any_axis(3, 3) = 1;
Eigen::Matrix3f N;
N <<
0, -nl.z(), nl.y(),
nl.z(), 0, -nl.x(),
-nl.y(), nl.x(), 0;
N = std::cos(ra) * I + (1.0f - std::cos(ra)) * nl * nl.transpose() + std::sin(ra) * N;
rotate_any_axis.block(0, 0, 2, 2) = N.block(0, 0, 2, 2);
return rotate_any_axis;
}
效果
请添加图片描述