解析QTransform的用法

QTransform本质与QMatrix3x3是一样的:二维平面上任何一个平移、伸缩、旋转的操作,或者其组合,都可以用3×3矩阵表述。

那么问题来了,假如我通过QTransform对一个条线段做了组合操作,比如说,先伸缩,再旋转,我应该如何生成这样的QTransform呢?

目录

例子1

例子2


先说结论:伸缩对应QTransform::scale,旋转对应QTransform::rotate,平移对应QTransform::translate。你的操作反映到QTransform上是++倒序++的--比如前文所说的先伸缩,再旋转,那么应先声明QTransform,再调用rotate,再调用scale

看下面两个例子

例子1

坐标为(100,50)的点,沿X方向拉伸2倍,然后顺时针旋转45°。

QTransform经历了下述变换:

cpp 复制代码
QTransform transform;
transform.rotate(45);
transform.translate(2,1);

既然是先拉伸,那么原来的(100,50)就变成了(200,50)

然后让(200,50)绕着原点(原点不会因为拉伸而移动)旋转45°。也就是让(0,0)-(200,50)的连线顺时针旋转45°。

这就要计算(0,0)-(200,50)的连线与X轴的夹角阿尔法:

利用python计算:α = numpy::arctan(50/200) = arctan(0.25)=0.245

显然,旋转后的线段与Y轴夹角β = 45° - 阿尔法 = arctan(1) - arctan(0.25)=0.54

而(0,0)-(200,50)的连线的长度可以用勾股定理获得:l = 206.155

于是解这个一个角等于0.54弧度,斜边等于206的直角三角形,得到旋转后的点变为:

106.066 176.777

而运行Qt程序,点击旋转后的点来打印该点坐标(下图左边棕色圆圈圈住的端点),打印的结果也是(106,177),见下图最下方的红色圆圈:

上图中,左边紫色圆圈标记的是变换前的点,即(100,50)

可见我们对QTransform的理解(操作倒序)是正确的。因为如果按照先旋转,再缩放来计算变换后的坐标,结果是不同的。

例子2

还是变换(100,50)。这次先沿X轴平移10,沿Y轴平移40;然后沿X压缩50%;最后逆时针旋转15°

平移后,坐标变为(110,90)

然后压缩,变为(55,90)

接下来旋转,计算思路就与例子1类似了。这里不赘述。python计算结果与Qt打印结果一致,说明我们对倒序的理解是正确的,否则结果将不同。

相关推荐
zhanghaha131411 小时前
Qt 类本质就是 C++ 的类,只是 Qt 框架扩展了一套【QObject 对象模型】
qt
Cx330❀18 小时前
深入浅出 Qt 绘图机制:从 QPainter 到四大图像类解析
开发语言·qt·ui·性能优化·图形渲染
Littlehero_12119 小时前
QT自定义控件之水泥厂组态(源码开源)
开发语言·qt
代钦塔拉1 天前
【C++/Qt 进阶】设计模式系列(6):桥接模式——把“两个独立变化的维度“拆开
c++·qt·设计模式
156082072191 天前
银河麒麟 Qt 可执行文件打包说明
开发语言·驱动开发·qt
Quz1 天前
QML GridView 布局:网格排布与排列方向
qt
Quz1 天前
QML GridView 动态:增删过渡与滚动定位
qt
沫璃染墨2 天前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程
代钦塔拉2 天前
【C++/Qt 进阶】设计模式系列(5):适配器模式——给“不兼容的接口“贴一层翻译膜
c++·qt·设计模式
把我格子衫拿来2 天前
VTK 9.5 与 Qt 6 联合开发:从嵌入三维窗口到可维护的桌面架构
c++·python·qt·vtk·三维可视化