【GAMES101】作业1学习总结

news2025/2/25 7:45:37

本系列博客为记录笔者在学习GAMES101课程时遇到的问题与思考。

  • GAMES101:课程官网
  • GAMES101:B站视频
  • GAMES101:相关文件下载(百度网盘)

一、基础题

通过Assignment1.pdf可以知道基础题的任务就是填充完整两个函数

  • get_model_matrix()
  • get_projection_matrix()

而其他的模块函数框架中都已经给定,只需要自己仔细阅读Assignment1.pdf中的内容并自己看源码尝试理解,本文不再赘述,理解不了也没事,知道是干啥用的就可以,不影响最后的作业结果。

接下来按MVP的顺序讲解本题需要填充的函数。

  1. get_model_matrix()
    由于题目要求是绕z轴旋转,由作业0可知旋转矩阵为:
    在这里插入图片描述
    先理解函数传入形参的含义,通过观察mian()函数可知rotation_angle传入的是旋转角度:

    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.
    
        float Radian_angle = rotation_angle / 180 * MY_PI; //Radian
        Eigen::Matrix4f Rz;
        Rz << 
            cos(Radian_angle), -sin(Radian_angle), 0, 0,
            sin(Radian_angle), cos(Radian_angle), 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1;
    
        model = Rz * model;
    
        return model;
    }
    

    其中float Radian_angle = rotation_angle / 180 * MY_PI;语句是因为math库中的sin和cos等三角函数是使用的弧度制,而传入的rotation_angle是角度制,需要先把角度转换为弧度。

  2. get_view_matrix()
    此函数作业框架已经给出,通过观察mian()函数可知eye_pos传入的是视角位置,也就是相机位置,接下来简单分析一下函数的作用:

    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;
    }
    

    视图矩阵的作用其实是将相机移到标准源点的过程,由此分析可以知道其实上述代码中的translate矩阵就是做了这么一件事,因为通过听课可知,其实平移操作就是在四阶矩阵的最后一列分别表示平移的距离。
    在这里插入图片描述
    由于eye_pos中存储的就是相机当前位置,但是要平移到源点必须要平移负值的参数,就比如(1, 0, 0)想要平移到源点必须在x轴平移-1的距离,所以由此可以轻松理解translate 矩阵所作的相机平移操作。

  3. get_projection_matrix()
    最后是投影矩阵,通过闫教授的分析可以知道,投影矩阵首先是要压缩图像,也就是将一个高分辨率的图像挤压成一个可以放入相机大小的图像,这样之后再进行正交投影就可以获得远处的物体投影至相机的图像了。

    对应的其实就是 M p e r s p → o r t h o M_{persp\rightarrow ortho} Mpersportho矩阵进行图像压缩和 M o r t h o M_{ortho} Mortho矩阵进行正交投影。通过闫教授的分析可以知道两个矩阵分别是:
    M p e r s p → o r t h o = ( n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ) M_{persp\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) Mpersportho= n0000n0000n+f100nf0
    M o r t h o = ( 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ) ( 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 0 − n + f 2 0 0 0 1 ) M_{ortho}=\left( \begin{matrix} \frac{2}{r-l}& 0& 0& 0\\ 0& \frac{2}{t-b}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right) \left( \begin{matrix} 1& 0& 0& -\frac{r+l}{2}\\ 0& 1& 0& -\frac{t+b}{2}\\ 0& 0& 0& -\frac{n+f}{2}\\ 0& 0& 0& 1\\ \end{matrix} \right) Mortho= rl20000tb20000nf200001 1000010000002r+l2t+b2n+f1
    首先分析一下投影矩阵的形参含义

    • eye_fov:为可视角度,也就是GAMES101_Lecture_04.pdf第30页中所示的张角
    • aspect_ratio:为宽高比,本题为1,也就是相机是正方形的
    • zNearzFar:为眼睛到相机的距离和眼睛到视图的距离,对应GAMES101_Lecture_04.pdf第30页中所示的 n n n f f f
    Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                          float zNear, float zFar)
    {
        zNear = -zNear;
        zFar = -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.
    
        Eigen::Matrix4f Mpersp_to_ortho;
        Mpersp_to_ortho << 
            zNear, 0, 0, 0,
            0, zNear, 0, 0,
            0, 0, zNear+zFar, -zNear*zFar,
            0, 0, 1, 0;
    
        float eye_fov_havle = eye_fov / 2 / 180 * MY_PI;
        float top = tan(eye_fov_havle) * -zNear; //because zNear is a nagetive number, but top is positive number
        float bottle = -top;
        float right = top * aspect_ratio;
        float left = -right;
        Eigen::Matrix4f Mortho, translation, canonical;
        translation << 
            1, 0, 0, -(right+left)/2,
            0, 1, 0, -(top+bottle)/2,
            0, 0, 1, -(zNear+zFar)/2,
            0, 0, 0, 1;
        canonical <<
            2/(right-left), 0, 0, 0,
            0, 2/(top-bottle), 0, 0,
            0, 0, 2/(zNear-zFar), 0,
            0, 0, 0, 1;
        Mortho = canonical * translation;
        projection = Mortho * Mpersp_to_ortho;
        return projection;
    }
    

    首先是最开始的两句zNear = -zNear;zFar = -zFar;,因为闫教授上课所推导的公式是基于我们处于z轴的正方向看向负方向的,所以式子中的 n n n f f f都是负数,而观察main()函数可知,调用该函数时传入的是正数,也就是这两个形参的含义是距离大小,所以我们要手动的将其调整为负值。

    下面的代码非常简单,上课认真听讲应该都能看懂,对应GAMES101_Lecture_04.pdf第23页和24页中的转换过程。

    然后根据作业0相同的步骤,先在对应的代码框架中新建build文件夹,再将run0.sh复制到该build文件夹中,并更改名字为run1.sh,并按照Assignment1.pdf中的步骤,将其中的内容更改为

    #/bin/bash
    cmake ..
    make -j4
    ./Rasterizer
    

    修改完成后执行./run1.sh,出现以下结果代表运行正确:
    在这里插入图片描述
    按A和D键可以将三角形绕z轴旋转,因为我们是往z轴负方向看的,所以按A键增大角度三角形应该是往逆时针旋转才对。

二、提高题

根据Assignment1.pdf中可知提高题需要构建get_rotation()函数实现绕任意轴的旋转。
闫教授上课讲到过的Rodrigues’ Rotation Formula可以实现该功能,位于课件GAMES101_Lecture_04.pdf的第10页,但是说实话我没有看懂这个公式的原理,只是依葫芦画瓢的实现了get_rotation()函数,也不清楚答案是否正确,先挖个坑,今后有时间再填吧[doge.jpg]。

Eigen::Matrix4f get_rotation(Vector3f axis, float 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.

    float Radian_angle = rotation_angle / 180 * MY_PI; //Radian

    Eigen::Matrix4f I, N, Rod;
    Eigen::Vector4f n(axis.x(), axis.y(), axis.z(), 0);
    Eigen::RowVector4f nT(axis.x(), axis.y(), axis.z(), 0);
    I <<
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;
    N <<
        0, -axis.z(), axis.y(), 0,
        axis.z(), 0, -axis.x(), 0,
        -axis.y(), axis.x(), 0, 0,
        0, 0, 0, 1;

    Rod = cos(Radian_angle) * I + (1 - cos(Radian_angle)) * n * nT + sin(Radian_angle) * N;
    Rod(3, 3) = 1; //Ensure correct proportion

    return Rod;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解c++---array和模板

目录标题 什么是array非类型模板参数函数模板的特化为什么会有特化如何进行特化类模板的特化部分特化模板特化参数的限制 模板的匹配规则模板的分离编译模板的总结 什么是array 在c语言里面使用一个括号就能申请到一段连续的空间&#xff0c;比如说想要申请一段空间用于存储10…

每日学术速递5.8

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Personalize Segment Anything Model with One Shot 标题&#xff1a;一键个性化细分任何模型 作者&#xff1a;Renrui Zhang, Zhengkai Jiang, Ziyu Guo, Shilin Yan, Junting Pa…

ArcMap创建格网统计图

目录 前言 一、人口数据获取 来源一&#xff1a;中科院地理所公开数据集 来源二&#xff1a;WorldPop数据集 二、人口格网统计步骤 1.创建渔网 2.人口数据处理 2.1 栅格转点 2.2 空间插值——处理人口缺失数据 2.3 空间连接——渔网人口统计 总结 前言 在科研中&am…

南华大学编译原理----词法分析器的设计与实现、语法分析器的设计与实现

下载链接&#xff1a;&#xff08;各位同学不需要充钱哈&#xff0c;这种我也没有收益&#xff0c;去淘宝上面找个代下&#xff0c;大概0.5元就能下载实验报告&#xff0c;用来给同学们参考&#xff0c;下载积分不是我设置的&#xff0c;是网站自己默认的&#xff09; --------…

English Learning - L3 作业打卡 Lesson1 Day1 2023.5.5 周五

English Learning - L3 作业打卡 Lesson1 Day1 2023.5.5 周五 引言&#x1f349;句1: Every people has its own way of saying things , its own special expressions.成分划分弱读连读语调自身问题&#xff1a; &#x1f349;句2: Many everyday American expressions are ba…

股票量价关系基础知识6----图解各阶段量价关系:价涨量平

图解各阶段量价关系&#xff1a;价涨量平 价涨量平是指股价上涨而成交量却变化不大&#xff0c;这可能是场外资金仍在观望&#xff0c;进场做多力量不大。 一、上涨初期的价涨量平 &#xff08;一&#xff09;形态分析 股价触底反弹后小幅上涨&#xff0c;成交量却持平&#x…

【认知提升思维篇】之向上越阶的跳圈思维(学霸的秘籍)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;普本…

软软件设计师算法上午题概念笔记

N皇后问题 **走迷宫 ** 以上q2不行 因为不能在同一行 这条路所有的都走不通所以需要回溯回溯至上一条路&#xff0c;把上一个皇后位置改变下 重新放皇后三 皇后四不能放所以回溯&#xff0c;发现皇后三也不能放 再往上回溯&#xff0c;发现2也不行那就回溯皇后1 总结&…

网络安全工程师必须面对的三个坎必备十大基础知识!

前言 我一个朋友老赵&#xff0c;老赵在一家大型互联网公司做高级网络安全工程师&#xff0c;从实习生到工程师整整待了六年。去年他们公司为了缩减成本&#xff0c;做了裁员&#xff0c;他也在其中&#xff0c;取而代之的是一个只有三年工作经验的 “新人” … 老赵想着&…

小牟Andorid下面MD5具体实现的思路总结

Android的开发往往需要一定数目demo 从今起MD5一些加密算法提取物 看看是如何实现的 首先&#xff0c;我们必须明确为什么加密&#xff1f; 1 数据安全处理 2 防止数据窃取 3 有效的避免恶意攻击 4 保证文件完整性 5 优化搜索 作为文件&#xff08;数据&#xff09;索引…

【Java零基础入门篇】第 ⑦ 期 - 常用类库

博主&#xff1a;命运之光 专栏&#xff1a;Java零基础入门 学习目标 掌握Java各种常用类库的使用方法。 目录 Java类库 字符串String String 概述 创建字符串对象的2种方式 String类的特点 创建字符串对象的2种方式 总结&#xff1a;创建字符串对象的2种方式区别 字符…

【C++】类和对象(下篇)

C类和对象下篇 构造函数的一点补充构造函数体赋值初始化列表explicit关键字 Static成员概念特性 友元友元函数友元类 内部类概念特性 匿名对象拷贝对象时的一些编译器优化几道例题 构造函数的一点补充 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#x…

股票量价关系基础知识2

内盘与外盘 外盘&#xff0c;是指在一个交易日获某段交易时间内&#xff0c;买方主动提价以委卖价成交的股数之和&#xff0c;也称为主动性买盘 内盘&#xff0c;是指在一个交易日获某段交易时间内&#xff0c;卖方主动降价以委买价成交的股数之和&#xff0c;也称主动性卖盘。…

flstudio20没有language选项,fl 21怎么也没有language选项

最新小伙伴们安装flstudio20没有language选项&#xff0c;是什么原因导致flstudio20没有language选项&#xff0c;兔八哥爱分享测试了&#xff0c;应该是flstudio20版本太低了&#xff0c;建议安装flstudio20.8以上版本&#xff0c;才可以flstudio20.8语言切换中文版。 flstud…

05- redis集群模式搭建(上) (包含云服务器[有坑])

目录 1. 准备环境: 2. 简介: -> 2.1 前言: -> 2.2 Redis集群架构实现了对redis的水平扩容 -> 2.3 redis cluster集群原理 3. 搭建后特别需要注意的问题 ->3.1 [重点]: 如果一个服务出现故障: 是否可以继续提供服务??? ---> 3.1.1 如果集群中故障re…

C++系列八:选择、循环与转向

选择、循环与转向 1. 选择语句2. 循环语句3. 转向语句4. 总结 1. 选择语句 选择语句使用条件来确定程序将执行哪些代码。在C编程中&#xff0c;选择语句有多种类型&#xff0c;包括if语句、switch语句和三元运算符。 &#xff08;1&#xff09;if语句 if语句是C编程中最常见…

Oracle EBS Interface/API(49)- AP付款取消API

快速参考 参考点内容功能导航N: AP->付款->录入->付款并发请求None基表AP.AP_CHECKS_ALLAPI参考下面介绍错误信息表None接口FormNone接口ReportNoneDebug ProfileNone详细例子参考如下实例官方文档None数据验证包None用户界面 Path:AP->付款->录入->付款-&g…

UNIX网络编程卷一 学习笔记 第十三章 守护进程和inetd超级服务器

守护进程是在后台运行且不与任何控制终端关联的进程。Unix系统通常有很多守护进程在后台运行&#xff08;约20到50个的量级&#xff09;&#xff0c;执行不同的管理任务。 守护进程由系统初始化脚本&#xff08;在开机时运行&#xff09;启动&#xff0c;而没有控制终端是系统…

华为交换机特殊场景使用mux vlan

场景主要用于&#xff1a; 设置两个vlan&#xff0c;每个vlan内的所有用户自动获取地址和能上外网&#xff0c;但是自个valn间用户都不能互相访问&#xff0c;每个用户又都可以 和其它vlan的用户通信。 官方版&#xff1a; 操作步骤 1.配置MUX VLAN 创建VLAN2、VLAN3和VLAN…

Python综合案例—利用tkinter实现计算器的程序

目录 一、导入 tkinter 库 定义全局变量 二、定义回调函数 三、创建窗口对象 四、创建标签控件 五、创建数字按钮 六、创建加、减、乘、除和等于按钮 七、创建清空按钮 八、总结 用Python实现计算器可以让我们更好地理解面向对象编程、GUI 编程和事件驱动编程等概念&a…