Qt坐标系统的变换
Qt 5.10.1
QTransform
QTransform类指定坐标系的2D变换。
变换指定如何平移,缩放,剪切,旋转或投影,并且通常在渲染图形时使用。
QTransform
与QMatrix
的不同之处在于它是一个真正的3x3矩阵,允许透视变换。 QTransform
的toAffine()
方法允许将QTransform
转换为QMatrix
。如果在矩阵上指定了透视变换,则转换将导致数据丢失。
QTransform
是Qt中推荐的转换类。
可以使用setMatrix()
,scale()
,rotate()
,translate()
和shear()
函数构建QTransform
对象。或者,它可以通过应用基本矩阵运算来构建。矩阵也可以在构造时定义,并且可以使用reset()
函数将其重置为单位矩阵(默认值)。
QTransform
类支持图形基元的映射:给定的点,线,多边形,区域或绘制路径可以使用map()
函数映射到此矩阵定义的坐标系。如果是矩形,可以使用mapRect()
函数转换其坐标。使用mapToPolygon()
函数,矩形也可以转换为多边形(映射到由此矩阵定义的坐标系)。
QTransform
提供了isIdentity()
函数,如果矩阵是单位矩阵则返回true,而isInvertible()
函数如果矩阵是非奇异的则返回true(即AB = BA = I)。如果reverse()
函数是可逆的(否则返回单位矩阵),invert()
函数返回该矩阵的逆矩阵,adjoint()
返回伴随矩阵。此外,QTransform
提供determinant()
函数,该函数返回矩阵的行列式。
最后,QTransform
类支持矩阵乘法,加法和减法,并且可以对流的对象进行流式处理和比较。
渲染图形
渲染图形时,矩阵定义了变换,但实际变换由QPainter
中的绘制过程执行。
默认情况下,QPainter
在自己的坐标系上运行。 QPaintDevice
的标准坐标系的原点位于左上角位置。 x值向右增加; y值向下增加。 有关完整说明,请参阅坐标系文档。
QPainter
具有在不使用QTransform
的情况下平移,缩放,剪切和旋转坐标系的功能。 例如:
void SimpleTransformation::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
painter.rotate(45);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QTransform");
}
虽然这些函数非常方便,但如果要执行多个转换操作,构建QTransform
并调用QPainter::setTransform()
会更有效。 例如:
void CombinedTransformation::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
QTransform transform;
transform.translate(50, 50);
transform.rotate(45);
transform.scale(0.5, 1.0);
painter.setTransform(transform);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QTransform");
}
基本矩阵运算
QTransform对象包含3 x 3矩阵。 m31(dx)和m32(dy)元素指定水平和垂直平移。 m11和m22元素指定水平和垂直缩放。 m21和m12元素指定水平和垂直剪切。 最后,m13和m23元素指定水平和垂直投影,m33作为附加投影因子。
QTransform使用以下公式将平面中的点转换为另一个点:
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
if (is not affine) {
w' = m13*x + m23*y + m33
x' /= w'
y' /= w'
}
点(x,y)是原点,(x’,y’)是变换点。通过对invert()
矩阵执行相同的操作,可以将(x’,y’)变换回(x,y)。
构造矩阵时可以设置各种矩阵元素,或者稍后使用setMatrix()
函数。它们也可以使用translate()
,rotate()
,scale()
和shear()
方便函数进行操作。可以使用m11(),m12(),m13(),m21(),m22(),m23(),m31(),m32(),m33(),dx()和dy()查看当前设置的值。
平移是最简单的变换。设置dx和dy将沿X轴移动坐标系dx单位,沿Y轴移动dy单位。可以通过设置m11和m22来完成缩放。例如,将m11设置为2,将m22设置为1.5将使高度加倍并将宽度增加50%。单位矩阵将m11,m22和m33设置为1(所有其他都设置为0)将点映射到自身。剪切由m12和m21控制。将这些元素设置为不等于零的值将扭曲坐标系。通过设置剪切因子和缩放因子来实现旋转。通过设置投影因子和缩放因子来实现透视变换。
这是使用基本矩阵运算的组合转换示例:
void BasicOperations::paintEvent(QPaintEvent *)
{
double pi = 3.14;
double a = pi/180 * 45.0;
double sina = sin(a);
double cosa = cos(a);
QTransform translationTransform(1, 0, 0, 1, 50.0, 50.0);
QTransform rotationTransform(cosa, sina, -sina, cosa, 0, 0);
QTransform scalingTransform(0.5, 0, 0, 1.0, 0, 0);
QTransform transform;
transform = scalingTransform * rotationTransform * translationTransform;
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
painter.setTransform(transform);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QTransform");
}
QMatrix
QMatrix类指定坐标系的2D变换。
矩阵指定如何平移,缩放,剪切或旋转坐标系,通常在渲染图形时使用。与QTransform相比,QMatrix不允许透视变换。 QTransform是Qt中推荐的转换类。
可以使用setMatrix()
,scale()
,rotate()
,translate()
和shear()
函数构建QMatrix对象。或者,它可以通过应用基本矩阵运算来构建。矩阵也可以在构造时定义,并且可以使用reset()
函数将其重置为单位矩阵(默认值)。
QMatrix类支持图形基元的映射:给定的点,线,多边形,区域或绘制路径可以使用map()
函数映射到此矩阵定义的坐标系。如果是矩形,可以使用mapRect()
函数转换其坐标。使用mapToPolygon()
函数,矩形也可以转换为多边形(映射到由此矩阵定义的坐标系)。
QMatrix提供了isIdentity()
函数,如果矩阵是单位矩阵则返回true,而isInvertible()
函数如果矩阵是非奇异的则返回true(即AB = BA = I)。如果该矩阵是可逆的,则invert()
函数返回该矩阵的逆矩阵(否则返回单位矩阵)。此外,QMatrix
提供了determinant()
函数,返回矩阵的行列式。
最后,QMatrix类支持矩阵乘法,并且可以对类的对象进行流式处理和比较。
渲染图形
渲染图形时,矩阵定义了变换,但实际变换由QPainter
中的绘制例程执行。
默认情况下,QPainter
在自己的坐标系上运行。 QPaintDevice
的标准坐标系的原点位于左上角位置。 x值向右增加; y值向下增加。 有关完整说明,请参阅坐标系文档。
QPainter
具有在不使用QMatrix
的情况下平移,缩放,剪切和旋转坐标系的功能。 例如:
void SimpleTransformation::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
painter.rotate(45);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QMatrix");
}
虽然这些函数非常方便,但如果要执行多个转换操作,构建QMatrix并调用QPainter::setMatrix()
会更有效。 例如:
void CombinedTransformation::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
QMatrix matrix;
matrix.translate(50, 50);
matrix.rotate(45);
matrix.scale(0.5, 1.0);
painter.setMatrix(matrix);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QMatrix");
}
基本矩阵运算
QMatrix对象包含3 x 3矩阵。 dx和dy元素指定水平和垂直平移。 m11和m22元素指定水平和垂直缩放。 最后,m21和m12元素指定水平和垂直剪切。
QMatrix使用以下公式将平面中的点转换为另一个点:
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
点(x,y)是原点,(x’,y’)是变换点。通过对invert()
矩阵执行相同的操作,可以将(x’,y’)变换回(x,y)。
构造矩阵时可以设置各种矩阵元素,或者稍后使用setMatrix()
函数。它们也可以使用translate()
,rotate()
,scale()
和shear()
方便函数进行操作。可以使用m11(),m12(),m21(),m22()来检索当前设置的值, dx()和dy()函数。
翻译是最简单的转变。设置dx和dy将沿X轴移动坐标系dx单位,沿Y轴移动dy单位。可以通过设置m11和m22来完成缩放。例如,将m11设置为2,将m22设置为1.5将使高度加倍并将宽度增加50%。单位矩阵将m11和m22设置为1(所有其他都设置为0)将点映射到自身。剪切由m12和m21控制。将这些元素设置为不等于零的值将扭曲坐标系。通过仔细设置剪切因子和比例因子来实现旋转。
这是使用基本矩阵运算的组合转换示例:
void BasicOperations::paintEvent(QPaintEvent *)
{
double pi = 3.14;
double a = pi/180 * 45.0;
double sina = sin(a);
double cosa = cos(a);
QMatrix translationMatrix(1, 0, 0, 1, 50.0, 50.0);
QMatrix rotationMatrix(cosa, sina, -sina, cosa, 0, 0);
QMatrix scalingMatrix(0.5, 0, 0, 1.0, 0, 0);
QMatrix matrix;
matrix = scalingMatrix * rotationMatrix * translationMatrix;
QPainter painter(this);
painter.setPen(QPen(Qt::blue, 1, Qt::DashLine));
painter.drawRect(0, 0, 100, 100);
painter.setMatrix(matrix);
painter.setFont(QFont("Helvetica", 24));
painter.setPen(QPen(Qt::black, 1));
painter.drawText(20, 10, "QMatrix");
}
QQuaternion
QQuaternion类表示由向量和标量组成的四元数。
四元数用于表示3D空间中的旋转,包括由x,y和z坐标指定的3D旋转轴,以及表示旋转角度的标量。
其他相关类
QVector2D
QVector3D
QVector4D
QMatrix3x3