1.get_model_matrix(float rotation_angle)
构建出旋转矩阵即可,注意角度要转换成弧度
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.
Matrix4f R;
float angle = rotation_angle / 180.0 * MY_PI;
R << cos(angle), -sin(angle), 0, 0,
sin(angle), cos(angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
model = R;
return model;
}
2.get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar):
因为这里输入的zNear和zFar都是正值,实际上应该是个负值,所以计算t的时候 对n取反
然后就是逐个构建出透视-->正交,正交变换矩阵,正交变换矩阵是一个先平移再缩放的顺序
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.
float angle = eye_fov/2 / 180.0 * MY_PI;
float t = tan(angle) * -zNear;//这里因为z的输入是正值,但实际上应该是个负值,所以应该取反
float r = aspect_ratio * t;
float n = zNear, f = zFar;
Matrix4f perspToOrthoMatrix,ortho,translate,scale;
perspToOrthoMatrix << n, 0, 0, 0,
0, n, 0, 0,
0, 0, n+f, -n*f,
0, 0, 1, 0;
translate << 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, -(n+f) / 2,
0, 0, 0, 1;
scale << 1 / r, 0, 0, 0,
0, 1 / t, 0, 0,
0, 0, 2 / (n - f), 0,
0, 0, 0, 1;
ortho =scale*translate;
projection = ortho * perspToOrthoMatrix;
return projection;
}
3.提高项
Eigen::Matrix4f get_rotation(Vector3f axis, float angle):是得到绕任意 过原点的轴的旋转变换矩阵。
很明显是通过罗德里格斯旋转公式
这里按照公式构建出矩阵即可,最后要变成四阶矩阵,因为要进行仿射变换
//提高部分
Matrix4f get_rotation_matrix(Vector3f axis, float angle)
{
Vector3f n = axis;//旋转轴
float rad = angle / 180.0 * MY_PI;//旋转角度
Matrix3f rMatrix;
Matrix3f identityMatrix = Matrix3f::Identity();
Matrix3f nMatrix;
nMatrix << 0, -n.z(), n.y(),
n.z(), 0, -n.x(),
-n.y(), n.x(), 0;
rMatrix = cos(rad) * identityMatrix + (1 - cos(rad)) * n * n.transpose() + sin(rad) * nMatrix;
Matrix4f rotationMatrix;//要进行仿射变换就要变成四阶矩阵
rotationMatrix << rMatrix(0, 0), rMatrix(0, 1), rMatrix(0, 2), 0,
rMatrix(1, 0), rMatrix(1, 1), rMatrix(1, 2), 0,
rMatrix(2, 0), rMatrix(2, 1), rMatrix(2, 2), 0,
0, 0, 0, 1;
return rotationMatrix;
}
最后就是将绕任意轴旋转应用到图像上,要先在在rasterizer.cpp加入接口函数设置旋转矩阵
void rst::rasterizer::set_rodrigues(const Eigen::Matrix4f& r)
{
rodrigues = r;
}
在draw函数里加入mvp矩阵的计算:
Eigen::Matrix4f mvp = projection * view * model * rodrigues;//计算mvp矩阵,因为绕任意轴旋转也是模型变换的一种,所以放在model矩阵的相邻位置
在rasterizer.hpp里声明接口函数和矩阵
public:
void set_rodrigues(const Eigen::Matrix4f& r);
private:
Eigen::Matrix4f rodrigues;
在main函数里面加入旋转轴和角度的参数输入:
Vector3f raxis;
float ra = 0, rangle = 0;
std::cout << "Please enter the axis and angle:" << std::endl;
std::cin >> raxis.x() >> raxis.y() >> raxis.z() >> ra;//定义罗德里格斯旋转轴和角
rangle = ra;
在循环里面加上按下r键就绕指定轴旋转
if (key == 'a') {
angle += 10;
}
else if (key == 'd') {
angle -= 10;
}
else if (key == 'r') {//按下r,再次绕给定任意轴旋转
rflag = true;
rangle += ra;
}
然后就大功告成了