欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)

程序员文章站 2022-07-14 09:50:18
...

首先我们看作业1的要求:

本次作业的任务是填写一个旋转矩阵和一个透视投影矩阵。给定三维下三个
v 0 (2 . 0 , 0 . 0 , 2 . 0) , v 1 (0 . 0 , 2 . 0 , 2 . 0) , v 2 ( 2 . 0 , 0 . 0 , 2 . 0) , 你需要将这三个点的坐
标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形 ( 在代码框架中,我们已
经提供了 draw_triangle 函数,所以你只需要去构建变换矩阵即可 ) 。简而言之,
我们需要进行模型、视图、投影、视口等变换来将三角形显示在屏幕上。在提供
的代码框架中,我们留下了模型变换和投影变换的部分给你去完成。
 
综上所述我们的要求就是写出模型变化,和投影变化。
 
首先我们(这里的模型变化他只需要我们写出一个绕z轴旋转的旋转矩阵就行了,回顾课堂)
games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)
我们已经求出来了,所以我们只需要抄写上去就完事了,这个较为简单
因为是绕z轴
 
Eigen::Matrix4f get_model_matrixws(float rotation_angle)
{
       Eigen::Matrix4f rotation;
    float angle = rotation_angle;

    angle = angle * MY_PI / 180.f; //角度转弧度
    rotation << cos(angle),-sin(angle),0,0,       //绕z的旋转矩阵
                sin(angle),cos(angle),0,0,
                0,0,1,0,
                0,0,0,1;

    Eigen::Matrix4f translate = Eigen::Matrix4f::Identity();

    return translate * rotation;  //输出
}

 

我们再看投影变化,因为我们采用的是透视投影,所以我们还需要进行透视投影转-正交投影,正交投影通过规则化,才能进行下一步
所以一共分成了三个步骤:
步骤一  透视投影转正交投影
步骤二:正交投影结果位移到原点,
步骤三然后进行规范化
首先对函数三个参数进行说明
我直接画一个图理解吧
games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)
根据老师所说的我们主要是要求这几个值
x坐标:[l,r]    y坐标 [b,t]    z坐标  [f,n]
z坐标已经直接给出[Near,zFar ]
y坐标也很好求:根据三角形y/n = tan(angle/2);
所以[-n*tan(angle/2),n*tan(angle/2) ]  这里符号反了是因为n是朝-z方向的
x轴坐标我们可以引用关键字来求解
(aspect_ratio)输出横竖比
所以  [- n * tan(angle/2) * aspect_ratio, n * tan(angle/2) * aspect_ratio ] 
求出这些值,我们可以直接更具课堂内容进行填写
位移到原点和规则化:
games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

    Eigen::Matrix4f M_p = Eigen::Matrix4f::Identity();//这个是投影转正交矩阵
    M_p << zNear,0,0,0,
               0,zNear,0,0,
               0,0,zNear+zFar,(-1.0*zNear*zFar),
               0,0,1,0;
    //[l,r]   [b,t]    [f,n]
    float angle = eye_fov*MY_PI/180;     //求角度
    float t = tan(angle/2)*-zNear;      //更具直角三角形性质求tb(高)
    float b = -1.0*t;
    float r = t*aspect_ratio;           //根据宽高比求(宽)
    float l = -1.0*r;

    Eigen::Matrix4f M_s = Eigen::Matrix4f::Identity(); //这个是将立方体进行规范化(-1,1)
    M_s << 2/(r-l),0,0,0,
               0,2/(t-b),0,0,
               0,0,2/(zNear-zFar),0,
               0,0,0,1;
               
    Eigen::Matrix4f M_t = Eigen::Matrix4f::Identity(); //这里是将三角形位移到原点
    M_t <<   1,0,0,(-1.0)*(r+l)/2,
               0,1,0,(-1.0)*(t+b)/2,
               0,0,1,(-1.0)*(zNear+zFar)/2,
               0,0,0,1;
    projection = M_s*M_t*M_p*projection;   //这里是左乘所以是先进行透视转正交,然后位移,然后规范化
    //projection = projection*M_p*M_t*M_s;

    return projection;

}

实验结果验证:

games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)

games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)

摁下a键的时候也有随之进行旋转,证明两个函数都没有错

//拔高训练个人思路1,我们做多次模型变化(绕z,绕x,绕y)反别进行旋转,

开始个人没想那么多所以直接单独认为三个方向旋转可以理解为三个方向分别旋转得出结果

目前遇到问题

games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)

games101- 计算机图形学-闫令琪教授-作业1,逐步详细解析(暂时不包括拔高)

如果对模型进行三次,他就会直接越界,就表明他是类似添加的机制调用三次,就会添加三个,但是实际上他只有一个四维矩阵所以出现越界

太晚了,明天再想着解决这个问题。

 

最后做一个说明,因为博主自己本人也是初次学习,人也比较垃圾,所以不是很懂,作业有看过别人是怎么写的,为啥这么写,这也能够,让我对之有一个正确的理解

比如有一个博主再写模型变化的时候,他添加了一个放大矩阵,让三角形更大,他放大了几倍,但是我也放大之后发现三角形三个顶点已经出去界面了,因此我分析得出他在透视投影犯了一个错误,就是他把矩阵相乘顺序写错了,导致绘制的模型很小,这里前面博主也碰到了,所以看到1他放大我就能明白他是为啥这么做,这一次作业收获的是:这是第一次通过作业来校验自己课程知识吸收了吗,以及第一次编程(图形学),能不能够吧学的知识运用到实际编程里面。慢慢来吧,亡羊补牢为时未完。

 
相关标签: 图形学