QTransform
基本原理
-
QTransform
类主要用于创建一个3*3的变换矩阵,该矩阵用于坐标系的2D变换。该类取代了QMatrix
类(此类已过时)。 -
QTransform
类通过操控变换矩阵来实现坐标变换,比如可进行矩阵的加、乘等运算,还可对矩阵类型进行判断(比如是否是满秩矩阵等) -
QTransform
类除了可通过操控其矩阵进行坐标变换外,还可以使用QTransform
类中内置的基本交换函数等对坐标进行变换 -
简单的坐标变换完全可以使用
QPainter
类中的基本坐标变换来完成 -
QTransform
类的变换矩阵如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 -
把
QTransform
类的变换矩阵与坐标变换矩阵相比,可得出如下规律其中m31和m32用于平移,m11和m22用于缩放,m21和m12用于错切(shear),m13和m23用于投影变化
枚举
- 变换矩阵类型
enum TransformationType{
TxNone = 0x00,//无变换
TxTranslate = 0x01,//平移
TxScale = 0x02,//缩放
TxRotate = 0x04,//旋转
TxShear = 0x08,//错切
TxProject = 0x10//投影
}
函数
QPainter
中与QTransform
相关的使用的函数- 世界矩阵:世界矩阵是表示点的空间位置的矩阵。世界矩阵第一行是模型自身向右的向量,第二行是向上的,第三行是向前的,第四行是位置,matrix是当前矩阵,combine表示false取代当前矩阵,true组合矩阵
void setWorldMatrixEnabled(bool enable)
bool worldMatrixEnabled() const
void setWorldTransform(const QTransform &matrix,bool combine =false)
void setTransform(const QTransform &transform,bool combine =false)
const QTransform & transform() const
const QTransform & worldTransform() const
- 世界矩阵:世界矩阵是表示点的空间位置的矩阵。世界矩阵第一行是模型自身向右的向量,第二行是向上的,第三行是向前的,第四行是位置,matrix是当前矩阵,combine表示false取代当前矩阵,true组合矩阵
- 构造函数
QTransform()
QTransform(qreal m11,qreal m12,qreal m13,qreal m21,qreal m22,qreal m23,qreal m31,qreal m32,qreal m33 =1.0)
QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
QTransform(const QMatrix &matrix)
QTransform(QTransform &&other)
QTransform(const QTransform &other)
- 设置和获取变换矩阵的元素
[ qreal m11() const; qreal m12() const; qreal m13() const ]
[ qreal m21() const; qreal m22() const; qreal m23() const ]
[ qreal m31() const; qreal m32() const; qreal m33() const ]
qreal dx() const; qreal dy() const
void setMatrix(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31,qreal m32, qreal m33)
- 内置的基本坐标变换函数
- 把坐标系沿轴axis逆时针旋转角度angle,并返回该矩阵的引用
QTransform &rotate(qreal angle,Qt::Axis =Qt::ZAxis)
- 该函数与rotate()函数相同,但角度angle是以弧度指定的
QTransform &rotateRadians(qreal angle,Qt::Axis axis =Qt::ZAxis)
- 缩放坐标系,并返回该矩阵的引用
QTransform &scale(qreal sx,sy)
static QTransform fromScale(qreal sx,qreal sy)
- 平移
QTransform &translate(qreal dx,qreal dy)
static QTransform fromTranslate(qreal sx, qreal sy)
- 错切变换
QTransform &shear(qreal sh, qreal sv)
- 把坐标系沿轴axis逆时针旋转角度angle,并返回该矩阵的引用
- 对变换矩阵的判断
- 若矩阵表示旋转变换,则返回true。180度或360度的旋转被视为缩
bool isRotating() const
- 若矩阵表示缩放变换,则返回true
bool isScaling() const
- 若矩阵表示平移变换,则返回true
bool isTranslating() const
- 若矩阵表示的是仿射(affine)变换,则返回true,否则返回false
bool isAffine() const
- 返回此矩阵的转换类型,注意:返回的值是最大枚举值,比如若矩阵即是缩放又是错切,则返回的值是TxShear
TransformationType type() const
- 若矩阵表示旋转变换,则返回true。180度或360度的旋转被视为缩
- 构建变换矩阵
- 重置为单位矩阵
void reset()
- 创建一个把单位正方形映射到一个四边多边形quad的变换矩阵trans。若构造了QTransform则返回true,否则返回false
static bool squareToQuad(const QPolygonF &quad,QTransform &trans)
- 创建一个把四边多边形quad映射到单位正方形的变换矩阵trans。若构造了QTransform则返回true,否则返回false
static bool quadToSquare(const QPolygonF &quad, QTransform &trans)
- 把此矩阵作为仿射矩阵返回,注意:若为透视转换,则转换后将导致数据丢失
const QMatrix &toAffine() const
- 重置为单位矩阵
- 与线性代数有关的函数
- 返回该矩阵的伴随(adjoint)矩阵
QTransform adjoint() const
- 返回该矩阵的行列式
qreal determinant() const
- 返回此矩阵的转置矩阵
QTransform transposed() const
- 返回此矩阵的逆矩阵,若矩阵是奇异的(非可逆的),则返回的矩阵是单位矩阵,若参数invertible有效(即不为0),则若矩阵可逆,则将其设置为true,否则将其设置为false
QTransform inverted(bool *invertible = Q_NULLPTR) const
- 若矩阵是单位矩阵,则返回true
bool isIdentity() const;
- 若矩阵是可逆的,则返回true
bool isInvertible() const
- 返回该矩阵的伴随(adjoint)矩阵
- 使用变换矩阵转换图形坐标
以下函数用于转换坐标,比如QPoint p1=matrix.map(point);表示把点使用变换矩阵matrix进行转换,然后返回该点的副本,相当于p1= point*matrix- 转换点
QPointF map(const QPointF &p) const;
QPoint map(const QPoint &point) const
QPoint operator*(const QPoint &point, const QTransform &matrix)
QPointF operator*(const QPointF &point, const QTransform &matrix)
- 转换线
QLine map(const QLine &l) const
QLineF map(const QLineF &line) const
QLineF operator*(const QLineF &line, const QTransform &matrix)
QLine operator*(const QLine &line, const QTransform &matrix)
- 转换多边形
QPolygonF map(const QPolygonF &polygon) const
QPolygon map(const QPolygon &polygon) const
QPolygonF operator*(const QPolygonF &polygon, const QTransform &matrix)
QPolygon operator*(const QPolygon &polygon, const QTransform &matrix)
- 转换裁剪区域
QRegion map(const QRegion ®ion) const
QRegion operator*(const QRegion ®ion, const QTransform &matrix)
- 转换绘制路径
QPainterPath map(const QPainterPath &path) const
QPainterPath operator*(const QPainterPath &path, const QTransform &matrix)
- 将x,y的转换结果保存在tx,ty中
void map(qreal x, qreal y, qreal *tx, qreal *ty) const
void map(int x, int y, int *tx, int *ty) const
- 若变换矩阵有旋转或错切,则以上函数返回的是转换后的边界矩形。要获取其准确的矩形,需使用函数mapToPolygon()
QRectF mapRect(const QRectF &rectangle) const
QRect mapRect(const QRect &rectangle) const
QPolygon mapToPolygon(const QRect &rectangle) const
- 转换点
示例
使用QTransform进行坐标转换
#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include <QRectF>
class aTransform :public QWidget
{
Q_OBJECT
private:
void init(){
}
protected:
void paintEvent(QPaintEvent *event) override{
Q_UNUSED(event)
QPainter painter;
painter.begin(this);
QBrush brush(QColor(255,255,1));
painter.setBrush(brush);//设置画刷
QRectF rect(0,100,55,55);//正方形
painter.drawRect(rect);
//变换1
// (m11, m12, m21, m22, dx, dy)
// ( 1 y x 1 20 0 ) 向dx移动20 dy移动0
QTransform &&transform = QTransform(1,0,0,1,20,0);
transform.rotate(-60);//向逆时针旋转60度
painter.setTransform(transform);//设置变换矩阵,combine为false时,代替变换矩阵
painter.drawRect(rect);
//变换2
transform.reset();//重置为单位矩阵
//[ m11=2, m12=0, m13=0]
//[ m21=0, m22=2, m23=0]
//[ m31=20, m32=0, m33=1]
//向X、Y方向放大两倍 (x,y,height,width)都会放大,向X再平移20
transform.setMatrix(2,0,0,0,2,0,20,0,1);
painter.setTransform(transform);
painter.drawRect(rect);
//变换3
//使用重载运算符进行矩阵乘法运算即先向X、Y方向放大两倍,再平移20,再平移150,旋转sinΘ =0.5
transform = transform *(QTransform(0.5,0.5,-0.5,0.5,150,0));
painter.setTransform(transform);
painter.drawRect(rect);
painter.end();
}
public:
aTransform(QWidget *p =nullptr) :QWidget(p){ init(); }
};
#endif // WIDGET_H
QTransform::map()函数的使用
#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include <QRectF>
class aTransform :public QWidget
{
Q_OBJECT
private:
void init(){
}
protected:
void paintEvent(QPaintEvent *event) override{
Q_UNUSED(event)
QPainter painter;
painter.begin(this);
QBrush brush(QColor(255,255,1));
painter.setBrush(brush);//设置画刷
QRectF rect(0,100,50,100);//正方形
painter.drawRect(rect);
QLineF line(100,0,100,555);//线段
painter.drawLine(line);
QTransform &&transform = QTransform({1,0,0,
0,1,0,
100,0,1}); //使用列表初始化,向x方向平移50
painter.setTransform(transform);
painter.drawRect(rect);
painter.drawLine(line);
//逆时针旋转90度
transform.rotate(90);
rect = transform.mapRect(rect);//使用map函数相当于矩阵乘法
line = line * transform ; //使用重载运算符
//painter.setTransform(transform);
painter.drawRect(rect);
painter.drawLine(line);
painter.end();
}
public:
aTransform(QWidget *p =nullptr) :QWidget(p){ init(); }
};
#endif // WIDGET_H
使用变换矩阵计算变换后的坐标值
#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include <QRectF>
class aTransform :public QWidget
{
Q_OBJECT
private:
void init(){
}
protected:
void paintEvent(QPaintEvent *event) override{
Q_UNUSED(event)
QPainter painter;
painter.begin(this);
QBrush brush(QColor(255,255,1));
painter.setBrush(brush);//设置画刷
QRectF rect(0,100,50,100);
painter.drawRect(rect);
QTransform transform;
transform.translate(50,0);//向x平移50
transform.rotate(-60);//以坐标原点轴逆时针旋转60
QPolygon polygon = transform.mapToPolygon(rect.toRect());//获取经过变换矩阵计算后的多边形
painter.drawPolygon(polygon);
qDebug()<<transform;
qDebug()<<polygon;
painter.end();
}
public:
aTransform(QWidget *p =nullptr) :QWidget(p){ init(); }
};
#endif // WIDGET_H