Game101现代计算机图形学作业1
- 一、作业描述
- 二、解决方法
- 一、模型变换
- 二、 投影变换
- 绕任意轴旋转
- 三、总结
- 四、参考和引用
一、作业描述
给定三维下三个点
v
0
(
2.0
,
0.0
,
−
2.0
)
v_0(2.0,0.0,-2.0)
v0(2.0,0.0,−2.0)、
v
1
(
0.0
,
2.0
,
−
2.0
)
v_1(0.0,2.0,-2.0)
v1(0.0,2.0,−2.0)、
v
2
(
−
2.0
,
0.0
,
−
2.0
)
v_2(-2.0,0.0,-2.0)
v2(−2.0,0.0,−2.0),你需要将三个点坐标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形。
1、实现模型变换和投影变换。
2、实现绕任意轴的旋转(可选)。
get_model_matrix(float rotation_angle)
:逐个元素地构建模型变换矩阵并返回该矩阵。在此函数中,你只需要实现三维中绕Z轴旋转的变换矩阵,而不用处理平移与缩放。
get_projection_matrix(float eye_fov,float aspect_ratio,float zNear,float zFar)
:使用给定的参数逐个元素地构建投影矩阵并返回该矩阵。
以及自行补充所需要的操作
二、解决方法
一、模型变换
绕Z轴的变换
R
z
(
α
)
=
(
c
o
s
(
α
)
−
s
i
n
(
α
)
0
0
s
i
n
(
α
)
c
o
s
(
α
)
0
0
0
0
1
0
0
0
0
1
)
R_z(alpha)=left(begin{matrix} cos(alpha)&-sin(alpha)&0&0\ sin(alpha)&cos(alpha)&0&0\ 0&0&1&0\ 0&0&0&1 end{matrix} right)
Rz(α)=⎝⎜⎜⎛cos(α)sin(α)00−sin(α)cos(α)0000100001⎠⎟⎟⎞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Eigen::Matrix4f get_model_matrix(float rotation_angle) { Eigen::Matrix4f model = Eigen::Matrix4f::Identity(); // TODO: Implement this function Eigen::Matrix4f rotation; float rot = rotation_angle/180*MY_PI; rotation << cos(rot), -sin(rot), 0, 0, sin(rot), cos(rot), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1; // Create the model matrix for rotating the triangle around the Z axis. model = rotation * model; // Then return it. return model; }
二、 投影变换
坐标的相对位置不变,光线是平行的,将物体变换到 [ − 1 , 1 ] 3 [-1,1]^3 [−1,1]3的立方体中(即坐标范围为[-1,1])。
M
o
r
t
h
o
=
(
2
r
−
l
0
0
−
r
+
l
r
−
l
0
2
t
−
b
0
−
r
+
b
r
−
b
0
0
2
n
−
f
−
n
+
f
n
−
f
0
0
0
1
)
M_{ortho}=left(begin{matrix} frac{2}{r-l}&0&0&-frac{r+l}{r-l}\ 0&frac{2}{t-b}&0&-frac{r+b}{r-b}\ 0&0&frac{2}{n-f}&-frac{n+f}{n-f}\ 0&0&0&1 end{matrix} right)
Mortho=⎝⎜⎜⎛r−l20000t−b20000n−f20−r−lr+l−r−br+b−n−fn+f1⎠⎟⎟⎞
M
p
r
e
s
→
o
r
t
h
o
=
(
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
)
M_{pres rightarrow ortho}=left(begin{matrix} n&0&0&0\ 0&n&0&0\ 0&0&n+f&-nf\ 0&0&1&0 end{matrix} right)
Mpres→ortho=⎝⎜⎜⎛n0000n0000n+f100−nf0⎠⎟⎟⎞
M
p
r
e
s
=
M
o
r
t
h
o
M
p
r
e
s
→
o
r
t
h
o
M_{pres}=M_{ ortho}M_{pres rightarrow ortho}
Mpres=MorthoMpres→ortho
M
p
r
e
s
=
(
2
n
r
−
l
0
l
+
r
l
−
r
0
0
2
n
t
−
b
b
+
t
b
−
t
0
0
0
n
+
f
n
−
f
−
n
f
n
−
f
0
0
1
0
)
M_{pres}=left(begin{matrix} frac{2n}{r-l}&0&frac{l+r}{l-r}&0\ 0&frac{2n}{t-b}&frac{b+t}{b-t}&0\ 0&0&frac{n+f}{n-f}&-frac{nf}{n-f}\ 0&0&1&0 end{matrix} right)
Mpres=⎝⎜⎜⎛r−l2n0000t−b2n00l−rl+rb−tb+tn−fn+f100−n−fnf0⎠⎟⎟⎞
Vertical Field of View(fovY) 是垂直可视角度
Aspect ratio是宽高比
-将fovY 和aspect转换成l,r,n,t
因为Z是取负方向的,所以t为负数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25Eigen::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(); Eigen::Matrix4f M1,M2; float n = zNear; float t=-tan(eye_fov/180/2*MY_PI)*n; M1<< 1/(t*aspect_ratio),0,0,0 ,0,1/t,0,0 ,0,0,2/(zNear-zFar),0 ,0,0,0,1; M2<< 1,0,0,0,0,1,0,0,0,0,1,-(zNear+zFar)/2,0,0,0,1; // TODO: Implement this function Eigen::Matrix4f pro; pro << zNear,0,0,0,0,zNear,0,0,0,0,zNear-zFar,-zNear*zFar,0,0,1,0; // Create the projection matrix for the given parameters. // Then return it. Eigen::Matrix4f Mortho=M1*M2; projection = Mortho*pro*projection; return projection; }
结果如下图:
绕任意轴旋转
R
(
n
,
α
)
=
c
o
s
(
α
)
I
+
(
1
−
c
o
s
(
α
)
)
n
n
T
+
s
i
n
(
α
)
(
0
−
n
z
n
y
n
z
0
−
n
x
−
n
y
n
x
0
)
R(n,alpha)=cos(alpha)I+(1-cos(alpha))nn^T+sin(alpha)left(begin{matrix} 0&-n_z&n_y\ n_z&0&-n_x\ -n_y&n_x&0\ end{matrix} right)
R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)⎝⎛0nz−ny−nz0nxny−nx0⎠⎞
[5]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37Eigen::Matrix4f get_model_matrix_axis(float rotation_angle,Eigen::Vector3f axis_start,Eigen::Vector3f axis_end) { Eigen::Matrix4f model = Eigen::Matrix4f::Identity(); // TODO: Implement this function Eigen::Matrix4f rotation = Eigen::Matrix4f::Identity();; Eigen::Vector3f axis; for(int i=0;i<3;i++){ axis[i] = axis_end[i] - axis_start[i]; } Eigen::Vector3f axisNorm = axis.normalized(); float rot = rotation_angle/180*MY_PI; Eigen::Matrix3f n(3,3); n<< 0,-axisNorm[2],axisNorm[1], axisNorm[2],0,-axisNorm[0], -axisNorm[1],axisNorm[0],0; Eigen::Matrix3f c1 = Eigen::Matrix3f::Identity() *cos(rot); Eigen::Matrix3f c2 = axisNorm*axisNorm.transpose() *(1-cos(rot)); Eigen::Matrix3f c3 = sin(rot) * n; // Create the model matrix for rotating the triangle around the Z axis. rotation.block(0,0,3,3) = c1+c2+c3; /* Eigen::AngleAxisf rotation_vector(rot,Eigen::Vector3f(axisNorm[0],axisNorm[1],axisNorm[2])); rotation.block(0,0,3,3) = rotation_vector.toRotationMatrix();*/ model = rotation * model; // Then return it. return model; }
三、总结
只实现基本要求,根据课程ppt还是比较容易实现的。
绕任意轴是看别人写的,公式以后还是要自己证明一下,不然感觉还是有点不理解,很难写出来。
四、参考和引用
[1] bilibili:GAMES101-现代计算机图形学入门-闫令琪
[2] 变换(二维与三维).pdf
[3] 变换(模型、视图、投影).pdf
[4] 罗德里格斯公式证明.pdf
[5] CSDN:GAMES101-现代计算机图形学学习笔记(作业01)
[6] GAMES101-现代计算机图形学作业链接
最后
以上就是留胡子斑马最近收集整理的关于Game101现代计算机图形学作业1一、作业描述二、解决方法三、总结四、参考和引用的全部内容,更多相关Game101现代计算机图形学作业1一、作业描述二、解决方法三、总结四、参考和引用内容请搜索靠谱客的其他文章。
发表评论 取消回复