Qt中QTransform的translate和rotate实现过程

先看一组数据

100
010
001
transform.translate(150,150);16315016315049069
100
010
1501501
transform.rotate(-15.0);16315031330049069
0.965926-0.2588190
0.2588190.9659260
1501501
transform.translate(-150,-150);163150346.268788252.70140349069.01532
0.965926-0.2588190
0.2588190.9659260
-33.711743.9341
163150162.557088146.63540349069.01532

|1 0 0 |
|0 1 0 |
|0 0 1 |矩阵是QTransform类对象transform的初始值,QTransform类对象的模型是这样的其中m31dx、m32dy是沿x、y轴的偏移量,也就是坐标系的偏移,可正可负。下面我们来分析transform和rotate函数都做了什么。

QTransform看起来像是变形的意思,但实际上是坐标系。 

transform.translate(150,150);是把坐标系移动和150,150位置

transform.rotate(-15.0);把坐标系逆时针旋转15°

transform.translate(-150,-150);是把坐标系还原到0,0位置

这三行的代码的意图是让坐标系中的点绕150,150旋转-15°。那第三行为什么要回到原来的位置,因为图像中的点都平移了150,150,需要消减这个影响。那么这几函数内部都做了什么呢?看不懂的可以结合表格来看,其中0.258819为sin15°的值,0.965926为cos15°的值。

transform.translate(150,150)做的是这样的变换

|1     0     0|   |1 0 0 |
|0     1     0|* |0 1 0 |
|150 150 0|   |0 0 1 |

 transform.rotate(-15.0);做的是这样的变换,先回到0,0位置,再平移后旋转

|1     0     0|   |1 0 0 |     |1       0     0|  |0.965926 -0.258819 0|
|0     1     0|* |0 1 0 |  *  |0       1     0|*|-0.965926 0.258819 0|
|150 150 0|   |0 0 1 |     |-150 -150 0|  |150         150           1|

最后一个transform.translate(-150,-150);由于我们只是绕150,150旋转而没有平移,所以要反向平移,

|1       0     0|  |0.965926 -0.258819 0|
|0       1     0|*|0.258819 0.965926   0|
|-150 -150 0|  |150         150            1|

当然此时的原点已经不是0,0了,而是-33.7117,43.934,可见0,0是按150,150旋转了-15°的,x变小y变大了。也就是0,0,1与结果矩阵的积,原坐标系的0,0在现坐标系中是-33.7117,43.934

值得注意的是,容易搞错和混乱的,矩阵乘法虽然不支持交换律,但是可以不按顺序相乘如ABC可以先算BC结果再与A相乘。因此要做什么变换可以先把Qtransform对象做好再map映射一下就可以了。在这个过程中要记住几个事 

 m11、m22控制缩放,m33一般是1,m13、m23一般是0,这里最容易搞乱的就是m31dx和m32dy这两个平移量。

  |0.965926 -0.258819 0|        //这里叫原点变换旋转矩阵
*|0.258819 0.965926   0|
  |150         150            1|这个乘法的效果是平移了150,150后以150,150为轴旋转,或者先旋转后平移也能说的通而

  |1       0     0|  |0.965926 -0.258819 0|
*|0       1     0|* |0.258819 0.965926   0|
  |150 150   0|  |0             0                 1| 是平移到150,150后坐标系以结果矩阵中m31dx和m32旋dy为中心旋转,上一个坐标变换竟然没办法分步完成!而Qt把我们认为本应该分步完成的以一个封装的形式完成就是transform.rotate(-15.0),它实际上是回到原点再执行乘原点变换旋转矩阵。

可以认为底层矩阵中

|m11 m12 m13|

|m21 m22 m23|

|m31 m32 m33|   m32dx,m33dx就包含着坐标原点信息,无论是哪种仿射变换。我们大概率要考

          dx     dy

虑到它的存在,除非是按照原点做仿射变换的这种小概率事件。而且它是增量的哦,我们设置乘矩阵时m31dx=0,m32dy=0只能代表 一个不太需要的结果。最终的结果还是要印出QTransform对象的矩阵结果才行。

    qDebug()<<transform.m11()<<transform.m12()<<transform.m13();
    qDebug()<<transform.m21()<<transform.m22()<<transform.m23();
    qDebug()<<transform.m31()<<transform.m32()<<transform.m33();

结果

0.965926 -0.258819 0
0.258819 0.965926  0
-33.7117 43.934       1就是绕0,0旋转-15度后平移 -33.7117,43.934,表现就是以绕150,150旋转-15度

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值