前言
本人是菜B,这节课的作业琢磨了很久,力求将每个知识点搞懂,特写下博客记录,既是总结方法论,也希望能帮助到大家
如何求绕z轴的旋转矩阵
这是我的课堂笔记
作业旋转矩阵求解
基本套公式就行,但需要注意C++的角度需要转换为弧度制
Matrix4f get_model_matrix(float rotation_angle) //绕z轴旋转
{
Matrix4f model = Matrix4f::Identity();
rotation_angle *= MY_PI / 180.0f;
Matrix4f translate;
translate <<
cos(rotation_angle), -sin(rotation_angle), 0, 0,
sin(rotation_angle), cos(rotation_angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
return translate * model;
}
如何求投影矩阵?
三步,先将投影转换为正交矩阵,再进行平移,最后标准化
1.利用相似三角形和远平面的中心点正交化不变的特点求出转换矩阵
结果为
2.本来应该先将摄像机平移到原点,但框架帮我们做了这个事情,现在直接将正交投影矩阵看成是立方体,平移到原点再标准化
这里需要注意,由于题目给的三角形是完全在-z轴的,而且我们使用右手系,这样就知道n和f应该是负的;函数参数传入的是正数,表示到近平面的距离和远平面的距离,如果直接使用会导致平移时-(n+f)/2为负数,也就是说反而远离了原点
作业投影矩阵求解
Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
Matrix4f PerToOr = Matrix4f::Identity();
PerToOr <<
zNear, 0, 0, 0,
0, zNear, 0, 0,
0, 0, zNear + zFar, -1.0 * zNear * zFar,
0, 0, 1, 0;
float n = -zNear; //右手系,从平移公式推导n和f为负数
float f = -zFar;
float angle = 0.5*eye_fov * MY_PI / 180;
float t = n * tan(angle);
float b = -t;
float r = t * aspect_ratio;
float l = -r;
//标准化
Matrix4f nor;
nor <<
2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, 2/(n-f), 0,
0, 0, 0, 1;
//平移
Matrix4f translate;
translate <<
1, 0, 0, -(r+l)/2,
0, 1, 0, -(t+b)/2,
0, 0, 1, -(n+f)/2,
0, 0, 0, 1;
Matrix4f projection = Matrix4f::Identity();
//先转换为正交投影变成立方体,再平移到原点,再标准化
return nor * translate * PerToOr * projection;
}
提高题
两步,先套公式,但公式给的结果是三维的,需要转换为齐次坐标
Matrix4f get_rotation(Vector3f n, float rotation_angle) //绕任意轴旋转
{
Matrix3f I = Matrix3f::Identity();
rotation_angle *= MY_PI / 180.0f;
Matrix3f N;
N <<
0, -n.z(), n.y(),
n.z(), 0, -n.x(),
-n.y(), n.x(), 0;
Matrix3f R = cos(rotation_angle) * I + (1 - cos(rotation_angle))*n * n.transpose() + sin(rotation_angle) * N; //套公式
Matrix4f model;
model <<
R.row(0), 0,
R.row(1), 0,
R.row(2), 0,
0, 0, 0, 1;
return model;
}
看了很多网上的答案也很接近,但测试的时候想绕x轴旋转就是没办法,希望能解决的大佬看到这里能联系我