Qt Coordinate System
Posted unclerunning
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt Coordinate System相关的知识,希望对你有一定的参考价值。
Qt 坐标系统
数学基础
Qt坐标系统
视口
和OpenGL一样,视口确定了画面在窗口(QWidget)中显示的区域,Qt的绘图坐标会完全映射到视口(View port)上,就像图示一样。
默认情况下,窗口和视口是重合的,视口的大小覆盖了整个窗口。
和OpenGL一样,Qt的QPainter也有设置视口的接口:painter.setViewport(startX, startY, width, hight);
例如,对于一个400x400(resize(400,400)
)的窗口:
void paintEvent(QPaintEvent *)
QPainter painter(this);
//在400x400的默认视口下画一个矩形区域,代表视口
painter.drawRect(100, 100, 200, 200);
//视口:限制窗口的绘图区域
painter.setViewport(100, 100, 200, 200);
painter.fillRect(100, 100, 200, 200, Qt::red);
上面的代码在400x400的逻辑画布中画了一个“正方形”,中心与画布中心重合,边界距离画布的边界为100。最后,Qt将画布线性地映射到视口中,结果如下:
平移变换
void paintEvent(QPaintEvent *)
QPainter painter(this);
//平移
painter.translate(150, 150);
//在平移之后的坐标系中绘图
painter.fillRect(0, 0, 100, 100, Qt::red);
上面的代码在400x400的逻辑画布中,先将坐标系移动到点(150,150)
,然后在移动之后的坐标系中画一个100x100的矩形。结果如下:
缩放变换
void paintEvent(QPaintEvent *)
QPainter painter(this);
painter.drawRect(100, 100, 200, 200);
//平移
painter.translate(150, 150);
//缩放
painter.scale(2, 2);
painter.fillRect(0, 0, 50, 50, Qt::red);
上面的代码在400x400的逻辑画布中,先将坐标系移动到点(150,150)
,接着对移动之后的坐标系的x轴和y轴的基向量放大,得到新的坐标系,然后在这个坐标系中画一个50x50的矩形。结果和上图一样:
setWindow
void paintEvent(QPaintEvent *)
QPainter painter(this);
painter.drawRect(100, 100, 200, 200);
painter.setWindow(-75, -75, 200, 200);
painter.fillRect(0, 0, 50, 50, Qt::red);
上面的代码等价于上节中的变换:setWindow ↔ 平移+ 缩放。
也可以等价为先缩放,再在缩放之后的坐标系中平移:
void paintEvent(QPaintEvent *)
QPainter painter(this);
painter.drawRect(100, 100, 200, 200);
//缩放
painter.scale(2, 2);
//平移
painter.translate(75, 75);
painter.fillRect(0, 0, 50, 50, Qt::red);
setWindow ↔ 平移 + 缩放 ↔ 缩放 + 平移
所以,其实setWindow就是一个平移和缩放的组合操作,得到一个新的坐标系。
旋转
void paintEvent(QPaintEvent *)
QPainter painter(this);
painter.translate(200, 200);
// 顺时针旋转 30 度
painter.rotate(30);
painter.fillRect(0, 0, 100, 100, Qt::red);
总结
OpenGL 3D坐标系统图示:
2D坐标系统图示:
与3D相比,2D的z坐标为0。
图中转换 T4T3T2 是Qt做的,我们在乎的是转换 T1=M1M2M3...Mn 。
T4T3T2
其实就是将画布(QWidget
)转换到1x1x1的空间。
T1=M1M2M3...Mn
就是我们做的一系列坐标系变换。
例如:
void paintEvent(QPaintEvent *)
QPainter painter(this);
//M1
painter.translate(200, 200);
//M2
painter.rotate(30);
painter.fillRect(0, 0, 100, 100, Qt::red);
上面的代码在画布(QWidget
)坐标系M中,先将坐标系进行平移变换
M1
得到坐标系M1,接着,对平移后的坐标系M1进行旋转变换
M2
得到坐标系M2。所以,当前的绘图坐标系(painter coordinate)就是M2,接下来使用的点的坐标都是坐标系M2中的点。Qt将M2中的点
(xM2,yM2,0)
与矩阵
T1
相乘,将点转换到M坐标系(QWidget
):
⎡⎣⎢xMyM0⎤⎦⎥ = T1 ⎡⎣⎢xM2yM20⎤⎦⎥
然后,将M坐标系中的点与矩阵
T4T3T2
相乘,将点转换到1x1x1空间中,OpenGL再将点映射到Qt设置的视口上,注意,此视口非painter.setViewport
设置的视口,此视口是为顶层窗口设置的视口,默认覆盖顶层窗口。
以上是关于Qt Coordinate System的主要内容,如果未能解决你的问题,请参考以下文章
初识OpenGL (-)坐标系统(Coordinate System)
初识OpenGL (-)坐标系统(Coordinate System)
Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?
DICOM-RT:放疗系统的坐标系统DICOM-RT Coordinate System
Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动
Silverlight & Blend动画设计系列十:Silverlight中的坐标系统(Coordinate System)与向量(Vector)运动