9.opengl-对qt中的QMatrix4x4进行矩阵实践

在上章8.opengl-矩阵总结(平移、缩放、旋转)_诺谦的博客-CSDN博客我们学习了矩阵基础知识,现在我们就运用在代码上瞧瞧.

1.Qt中的矩阵类

在QT中,提供的矩阵类有4种:

QMatrix

用来实现2D空间的一个2X2矩阵、并且提供了旋转、缩放、位移等函数给我们使用,由于它只有2X2,所以并不支持透视变换(因为没有多余的参照元素)

QTransform

用来实现2D空间的一个3X3矩阵、并且提供了旋转、缩放、位移等函数给我们使用,QTransform QMatrix 的不同之处在于它是一个真正的 3x3 矩阵,允许透视变换。

QMatrix4x4

用来表示3D空间中的一个4X4矩阵,可以与向量(QVector3D )或者矩阵(QMatrix4x4 )进行加减乘运算(与向量只能进行乘运算)、并且提供了旋转、缩放、位移等函数给我们使用

QGenericMatrix

是一个模板类template <int N, int M, typename T> , 可以定义任意一个N列M行的矩阵,只是提供了与矩阵的+、-、*运算符,没有缩放位移相关函数

示例如下所示:

QGenericMatrix<5,4, int> m;

m.fill(1);  // 填充所有元素为1

qDebug()<<m(3,3);   // 打印3行3列值(行列数是从0开始的)

PS:

由于opengl主要面向3d场景,所以用的最多的是QMatrix4x4类.接下来我们便使用QMatrix4x4类来实践一下.

2.QMatrix4x4中的translate函数和scale函数使用

由于我们后面教程在3D空间里使用,所以向量的话使用QVector3D类或者QVector4D(比QVector3D多了一个w分量)

translate函数和scale函数定义如下所示:

void QMatrix4x4::translate(const QVector3D &vector);
// 平移函数,获取vector的xyz分量,并将该分量作为平移量赋到当前矩阵中.
void QMatrix4x4::scale(float x, float y, float z)
// 缩放函数,其本质就是将矩阵的对角线上的分量分别乘以参数分量.比如调用scale(1,2,2).那么就是构造一个x大小保持不变、y和z放大2倍的矩阵

位移+缩放代码如下所示:

    QVector4D vec(1.0f, 0.0f, 0.0f, 1.0f);       // 定义一个x为1,y为0,z为0的向量
    QMatrix4x4 m;                                // 定义一个矩阵,由于未初始化,所以构造函数会初始化为一个单位矩阵

    m.translate(QVector3D(1, 2, 4));             // 传递一个位移向量,获取一个位移矩阵
    m.scale(2,2,2);
    qDebug()<<m;

    vec = m * vec;                               // 将vec向量放大2倍后再位移(1,2,4)个单位
    qDebug()<<vec.x()<<vec.y()<<vec.z();

运行打印:

 可以看到,首先将(1,0,0)放大两倍变成(2,0,0),然后位移(1,2,4)个单位,得到(3,2,4)

上章遗留的分析验证

在我们上章分析过,如果缩放放在前面,位移放在后面,会导致整个都进行缩放,如下图所示:

测试如下所示:

    QVector4D vec(1.0f, 0.0f, 0.0f, 1.0f);      
    QMatrix4x4 m;

    m.scale(2,2,2);                         // 缩放放在位移前面

    m.translate(QVector3D(1, 2, 4));          

    qDebug()<<m;

    vec = m * vec;                               
    qDebug()<<vec.x()<<vec.y()<<vec.z();

 运行打印:

可以看到执行结果是倒置的,其结果是先将(1, 0 , 0)位移(1,2,4)个单位,得到(2,2,4).最后在放大2倍,得到(4,4,8)。

总结:

我们使用矩阵组合时,应该遵循从右往左读法,对于函数而言就是从下往上解读.所以下面代码:

m.translate(QVector3D(1, 2, 4));    // 最后执行位移

m.scale(2,2,2);                     // 先执行缩放

实际是先缩放再位移.

3.QMatrix4x4中的rotate函数使用

函数定义如下所示:

void QMatrix4x4::rotate(float angle, float x, float y, float z = 0.0f);
// 沿着向量(x,y,z)旋转angle角度.比如rotate(90, 0, 0, 1)就是沿着z轴旋转90°

示例如下所示:

    QVector4D vec(2.0f, 0.0f, 0.0f, 1.0f);       // 定义一个x为1,y为0,z为0的向量

    QMatrix4x4 m;

    m.rotate(90, 0,0,1); 
    qDebug()<<m;
 
    vec = m * vec;

    qDebug()<<vec.x()<<vec.y()<<vec.z();

运行打印:

 可以看到沿着z轴旋转90°后,原来的x坐标值变成了y坐标值.

除此之外,还有其它常用函数,如下所示:

void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)
//透视投影, verticalAngle: 垂直角度(也就是裁剪窗口的高度),值越大,那么物体越小
// aspectRatio: 横纵比(由视口的宽除以高所得),值越大则越宽,比如宽高为100X50,那么就等于2
// nearPlane: 设置近平面的距离(一般设置为0.1)
// farPlane: 设置远平面的距离(一般设置为100)

void QMatrix4x4::ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane)
//正射投影, left right, bottom, top : 设置观察箱(平截头体)的上下左右坐标
// nearPlane: 设置近平面的距离
// farPlane: 设置远平面的距离

void QMatrix4x4::lookAt(const QVector3D &eye, const QVector3D &center, const QVector3D &up)
//获取lookAt矩阵.
//eye: 设置摄像机(眼睛)位置,比如QVector3D(0,0,3)
//center:表示摄像机(眼睛)正在看的视图的中心,比如原点QVector3D(0,0,0)
//up:眼睛的上向量,一般为QVector3D(0,1,0),通过该向量就能获取到眼睛的右轴和上轴

PS: 矩阵中常用的函数使用已经使用完毕,后面遇到新的再来进行补充~

未完待续,下章我们学习让opengl里的图形进行旋转移动.

opengl技术交流群:929155430

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诺谦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值