Games101-系列课程笔记-作业1

Games101-系列课程笔记


本篇博客内容为Games-101系列课程的作业1,有兴趣的小伙伴可前往GAMES101官网下载相关内容。GAMES101官网

代码说明详见代码注释


模型变换(绕Z轴旋转)

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.
    Eigen::Matrix4f rot;
    rot<< cos(rotation_angle*M_PI/180),-sin(rotation_angle*M_PI/180),0,0,\
    sin(rotation_angle*M_PI/180),cos(rotation_angle*M_PI/180),0,0,\
    0,0,1,0,\
    0,0,0,1;
    model=rot*model;

    return model;
}

PS:由于输入的角度是角度制,需要用rotation_angle*M_PI/180转换为弧度制。


视角变换

Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
{
    Eigen::Matrix4f view = Eigen::Matrix4f::Identity();

    Eigen::Matrix4f translate;
    translate << 1, 0, 0, -eye_pos[0], 0, 1, 0, -eye_pos[1], 0, 0, 1,
        -eye_pos[2], 0, 0, 0, 1;

    view = translate * view;

    return view;
}

这段代码将相机位置eye_pos移到原点上。


透视投影

/*
@Params:
eye_fov:视角(field of view)
aspect_ratio:宽高比
zNear:近平面距原点距离
zFar:远平面距原点距离
@Return:
Eigen::Matrix4f:四维变换矩阵
*/

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 n,f,l,r,t,b;
    Eigen::Matrix4f M_o,M_persp_ortho,M_t,M_s;

    n=zNear;
    f=zFar;

	/*透视变换"压缩"为正交变换的转化矩阵*/
    M_persp_ortho<<n,0,0,0,
    0,n,0,0,
    0,0,n+f,-n*f,
    0,0,1,0;
    
    /*根据近平面距离和宽高比,计算视锥在近平面上的尺寸*/
    t=n*tan(eye_fov*M_PI/180/2);
    b=-t;
    r=t*aspect_ratio;
    l=-r;

	/*正交投影Step1:把压缩后的视锥移到坐标原点*/
    M_t<<1,0,0,-(r+l)/2,
    0,1,0,-(t+b)/2,
    0,0,1,-(n+f)/2,
    0,0,0,1;

	/*正交投影Step2:把Step1完成后的视锥压缩为[-1,1]^3的标准立方体*/
    M_s<<2/(r-l),0,0,0,
    0,2/(t-b),0,0,
    0,0,2/(n-f),0,
    0,0,0,1;

	/*正交投影*/
    M_o=M_s*M_t;
	/*透视投影*/
    projection=M_o*M_persp_ortho*projection;
    
    return projection;
}

提高项

在 main.cpp 中构造一个函数,该函数的作用是得到绕任意过原点的轴的旋转变换矩阵。

Eigen::Matrix4f get_rotation(Vector3f axis, float angle){
    Eigen::Matrix4f res;
    Eigen::Matrix3f base = Eigen::Matrix3f::Identity();
    Eigen::Vector3f n(axis[0],axis[1],axis[2]);
    Eigen::Matrix3f tt;
    Eigen::Matrix3f res_temp;
    tt << 0,-axis[2],axis[1],\
        axis[2],0,-axis[0],\
        -axis[1],axis[0],0;
    /*罗德里格斯公式*/
    res_temp=cos(angle*M_PI/180)*base+(1-cos(angle*M_PI/180))*n*n.transpose()+sin(angle*M_PI/180)*tt;
    /*将旋转矩阵扩展成齐次坐标形式*/
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(i==3||j==3){
                if(i!=j)
                    res(i,j)=0;
                else
                    res(i,j)=1;
            }
            else{
                res(i,j)=res_temp(i,j);
            }
        }
    }
    return res;
}

利用罗德里格斯公式,对模型绕axis向量逆时针旋转angle角度。


参考

[1]. GAMES101_Lecture_02、03、04、05.pdf
[2]. Shirley P , Marschner S R . Fundamentals of Computer Graphics[M]. AK Peters, 2005.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值