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(α)00sin(α)cos(α)0000100001

Eigen::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=rl20000tb20000nf20rlr+lrbr+bnfn+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) Mpresortho=n0000n0000n+f100nf0
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=MorthoMpresortho
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=rl2n0000tb2n00lrl+rbtb+tnfn+f100nfnf0
Vertical Field of View(fovY) 是垂直可视角度
Aspect ratio是宽高比
在这里插入图片描述
-将fovYaspect转换成l,r,n,t
在这里插入图片描述
因为Z是取负方向的,所以t为负数

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();
    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+(1cos(α))nnT+sin(α)0nznynz0nxnynx0
[5]

Eigen::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-现代计算机图形学作业链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值