【Games101作业】绘制三角形,并使其旋转

git路径

https://github.com/heweisheng/Game101HomeWork/tree/main/GAMES101_Homework1_S2021/Homework1/Assignment1

绕z轴旋转

由于绕z轴旋转相当于二维的绕原点旋转,直接套用二维的公式即可。关于二维旋转矩阵的推算过程可以参考第三节的 18分钟
这里跳过推算的过程,直接使用结果矩阵,参考上面get_view_matrix的方法,模拟写法。得出旋转矩阵的定义方法:

Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    //实现思路,参考上面的函数,identity获取单位矩阵,不知道为什么要乘单位矩阵
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
    //弧度制转换
    float rr = (float)(rotation_angle / 180.0 * MY_PI);
    Eigen::Matrix4f rotate;
    // z轴旋转矩阵,由于是绕z轴转,仅x,y变化,可以直接使用二维旋转的公式+齐次坐标
    //二维旋转矩阵推算 https://www.bilibili.com/video/BV1X7411F744?p=3&vd_source=657636f6c75d9280607e5f9ee048d9d4 18分钟
    rotate << cos(rr), -sin(rr), 0, 0,
        sin(rr), cos(rr), 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;

    // TODO: Implement this function
    // Create the model matrix for rotating the triangle around the Z axis.
    // Then return it.
    model = rotate * model;
    return model;
}

转换标准[-1,1]的透视投影

按照闫老师的课程,透视投影转-1,1的标准立方体的做法是先转换成正交投影,再平移,再缩小长宽。
先做正交转换,转换推导可以参考:
https://blog.csdn.net/qq_38904659/article/details/107523815

这里涉及到第四节课跟第五节课两节课的内容
大致思路是利用等比条件算出x,y轴的矩阵关系,然后根据远近平面上的点投射到自身平面时等于本平面推出矩阵第三行。
zNear, 0, 0, 0,
0, zNear, 0, 0,
0, 0, zNear + zFar, -zNear * zFar,
0, 0, 1, 0
完成正交转换后,现在有视野角度,相机与近平面距离,宽高比,根据tan推算出 top,bottom的位置,再根据长宽比推出left,right

    //根据三角形定理,求出left top bottom right
    float fov= eye_fov / 2;//投影平面与视野呈垂直,平面到眼睛连线,到顶部,底部的夹角为角度/2 
    float fovr =  (float)(fov * MY_PI / 180.0); //求弧度制

    

    float t = zNear * tan(fovr);//视角到顶点距离 对边/直角边=tan 对边=tan*直角边
    float b = -t;//同上 top为正方向 bottom负方向
    float r = aspect_ratio * t;//可视平面宽高比获取左右方位长度 w/h=aspect w=aspect*h r=w/2
    float l = -r;//同上 right正方向 left负方向

先做平移,要让原点处中心,x=-(r+l)/2,y=-(b+t)/2 z=-(f+n)/2

做缩放,映射到-1,1的范围
x=2/(r-l) y=2/(b-t) z=2/(n-f)

但是发现三角形倒过来了,具体原因闫老师课程有说是使用的坐标系不相同,那我们把x,y 再乘-1就可以倒过来了
最终是:

//作业要求时这里生成标准化矩阵
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();
    //透视投影,先把透视转成正交投影,再变回透视投影显示,利用相似三角形推算出x,y的数值
    Eigen::Matrix4f ortho;
    //公式推导 第四节 https://www.bilibili.com/video/BV1X7411F744?p=4&vd_source=657636f6c75d9280607e5f9ee048d9d4 1小时01分左右
    ortho << zNear, 0, 0, 0,
        0, zNear, 0, 0,
        0, 0, zNear + zFar, -zNear * zFar,
        0, 0, 1, 0;

    //根据三角形定理,求出left top bottom right
    float fov= eye_fov / 2;//投影平面与视野呈垂直,平面到眼睛连线,到顶部,底部的夹角为角度/2 
    float fovr =  (float)(fov * MY_PI / 180.0); //求弧度制

    

    float t = zNear * tan(fovr);//视角到顶点距离 对边/直角边=tan 对边=tan*直角边
    float b = -t;//同上 top为正方向 bottom负方向
    float r = aspect_ratio * t;//可视平面宽高比获取左右方位长度 w/h=aspect w=aspect*h r=w/2
    float l = -r;//同上 right正方向 left负方向

    Eigen::Matrix4f trans, scale,upend;
    //到原点
    trans << 1, 0, 0, -(r + l) / 2,
        0, 1, 0, -(t + b) / 2,
        0, 0, 1, -(zNear + zFar) / 2,
        0, 0, 0, 1;


    //压缩到-1,1的矩阵
    scale << 2 / (r - l), 0, 0, 0,
        0, 2 / (t - b), 0, 0,
        0, 0, 2 / (zNear - zFar), 0,
        0, 0, 0, 1;



    
    //内容上下颠倒 坐标系变换下
    upend<<-1,0,0,0,
    0,-1,0,0,
    0,0,1,0,
    0,0,0,1;

    
    projection = upend*scale*trans*ortho*projection;
    return projection;
    // TODO: Implement this function
    // Create the projection matrix for the given parameters.
    // Then return it.
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值