QT - 图像处理 ( 4 ) - QTransform 之 坐标变换矩阵

数学知识和计算机图形学方面的知识
12.12.1 基本数学知识

1、齐次坐标

二维空间中的点可使用(x, y)表示,但在计算机图形学中使用齐次坐标表示点更为方便,齐次坐标把点表示为三元组,即在(x,y)基础上增加一维表示为(x, y, w),其中w是一个非零值
每个点有很多个不同的齐次坐标表示(只要其中一个是另一个的倍数即可),比如(1, 2, 5),(2,4, 10),(4, 8, 20);都表示同一个点,通常会使用w去除齐次坐标,从而一个点被表示为(x/w, y/w, 1),这样,每一个二维坐标点都可以使用三维的齐次坐标来表示,同理,三维坐标点(x,y,z);可使用四维的齐次坐标表示为(x, y, z, 1);比如(2,5,9)的齐次坐标为(2,5,9,1);
使用齐次坐标后,所有的坐标变换公式都可以使用如下矩阵相乘的形式来表示,

在这里插入图片描述

2、坐标变换公式
以下各式中,dx和dy表示平移距离,Sx和Sy表示缩放系数,θ表示绕原点逆时针旋转的角度,P1(x1, y1)为坐标变换后的

点,P(x,y)为变换前的点。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、坐标的复合变换
坐标的复合变换是指多个坐标变换序列的组合。
①、连续平移变换(其结果是平移相加)

把点P平移至点P1再平移至P2,则其平移公式的推导步骤为
在这里插入图片描述
由以上推导过程可见,对复合的坐标变换序列,只需计算其变换矩阵即可,以上规则同样适用于其他更复杂的复合变换,对于之后的变换,将只写出变换矩阵的计算。
下面为坐标平移复合变换后的计算过程。
在这里插入图片描述

在这里插入图片描述

5、总结

由以上讲解可知,只要给出变换矩阵,便可对其进行坐标变换,因此在计算机编程中,通常只需给出一个变换矩阵,然后给矩阵各元素赋予需要的值便可对其进行各种坐标变换。
6、其他
对于三维空间的坐标变换,其原理与二维类似,其坐标变换矩阵为
在这里插入图片描述

12.12.2 使用QPainter类中的基本变换函数进行坐标变换

默认情况下,QPainter是在自已所关联的绘制设备的坐标系(通常为像素)上运行的,绘制设备默认坐标系的原点位于左上角,X轴向右增长,Y轴向下增长。
2、QPainter类中的基本坐标变换函数如下
在这里插入图片描述
3、QPainter类中与绘制状态有关的函数如下
在这里插入图片描述

示例12.20:使用QPainter类中的基本坐标变换函数变换坐标

void paintEvent(QPaintEvent *e)
{
  QPainter pr(this);
  QBrush bs(QColor(1,111,1));    
  pr.setBrush(bs);    
  QRectF r(0,11,22,55);
  pr.drawRect(r);

  //变换1:平移(50,10)
  pr.translate(50,10);		
  pr.drawRect(r);  	
  pr.save();	//保存状态

  //变换2:平移(50,50),缩放2倍(Y向),逆时针旋转60度
  pr.translate(50,50);    
  pr.scale(1,2);    
  pr.rotate(-60);    
  pr.drawRect(r);
  QTransform t=pr.transform();	 //获取变换2的变换矩阵
  qDebug()<

运行结果(见图12-55)
在这里插入图片描述

现以变换2计算其变换矩阵

注意:在使用QPainter类中的基本坐标变换函数进行复合坐标变换时,其变换矩阵应按相反的顺序进行计算。因此计算变换2的矩阵时应按旋转、缩放、平移的顺序进行计算,如下所示
在这里插入图片描述

12.12.3 使用变换矩阵(QTransform类)进行坐标变换

1、QPainter类中与QTransform类有关的函数如下
QT - 图像处理 ( 4 ) - QTransform 之 坐标变换矩阵_第1张图片

2、QTransform类
QTransform类主要用于创建一个3*3的变换矩阵,该矩阵用于坐标系的2D变换。该类取代了QMatrix类(此类已过时)。QTransform类通过操控变换矩阵来实现坐标变换。另外QTransform类还可对矩阵进行操作,比如可进行矩阵的加、乘等运算,还可对矩阵类型进行判断(比如是否是满秩矩阵等)。
QTransform类除了可通过操控其矩阵进行坐标变换外,还可使用QTransform类中内置的基本变换函数(比如QTransform::scale()、QTransform::scale()等)对坐标进行变换,这些函数的使用方法与QPainter类中的相应函数是相同的。简单的坐标变换完全可使用QPainter类中的基本坐标变换函数来完成,使用QTransform类可以把多个坐标变换组织在一起,然后在需要时使用。
QTransform类的变换矩阵如下

在这里插入图片描述

注:公式18~22其实就是使用的如下矩阵乘法计算出来的(读者可自行计算),在没有投影变换的情形下,w1直接取整数值1即可。因此在使用QTransform类进行坐标变换时,也可使用如下的矩阵形式计算变换后的坐标值。
在这里插入图片描述

把QTransform类的变换矩阵与坐标变换矩阵相对比,可得出如下规律m31和m32用于平移,m11和m22用于缩放,m21和m12用于错切(shear),m13和m23用于投影变换,m33是一个额外的投影因子,设置m11,m12,m21,m22可实现旋转变换。注:投影变换是一个比较复杂的变换,包括透视投影(图12-56为透视投影的一个简图)和平行投影,关于投影变换的内容请参阅《计算机图形学》课程。

在这里插入图片描述

12.12.4 QTransform类中的函数

1、构造函数
在这里插入图片描述
2、设置和获取变换矩阵的元素
在这里插入图片描述
3、QTransform内置的基本坐标变换函数在这里插入图片描述
4、对变换矩阵的判断
在这里插入图片描述
5、构建变换矩阵

在这里插入图片描述
6、与线性代数有关的函数
在这里插入图片描述
7、使用变换矩阵转换图形坐标
以下函数用于转换坐标,比如QPoint p1=matrix.map(point);表示把点使用变换矩阵matrix进行转换,然后返回该点的副本。等效于p1= point*matrix;具体应用见示例12.22

在这里插入图片描述

8、下面为重新实现的操作符函数
在这里插入图片描述

示例12.21:使用QTransform类(变换矩阵)进行坐标变换(见图12-57)

//注意:变换矩阵应按设计的相反顺序计算,比如若设计为平移T、旋转R、缩放S,则矩阵计算应为S∙R∙T
void paintEvent(QPaintEvent *e)
{
  QPainter pr(this);  
  QBrush bs(QColor(1,111,1)); 
  pr.setBrush(bs);
  QRectF r(0,55,22,55);

  //变换1(平移、旋转)
  QTransform t(1,0,0,1,20,0); 	//x方向平移20
  t.rotate(-60);       		//使t再逆时针旋转60度。
  pr.setTransform(t);  		//设置变换矩阵为t
  qDebug()<

在这里插入图片描述

示例12.22:QTransform::map()函数的使用(见图12-58)
void paintEvent(QPaintEvent *e)
{
  QPainter pr(this);  
  QBrush bs(QColor(1,111,1));   
  pr.setBrush(bs);
  QRectF r(0,55,22,55); 
  QLineF n(50,0,50,555);
  pr.drawLine(n);    		
  pr.drawRect(r);

  QTransform t;    		
  t.translate(50,0);	//x方向平移50
  QRectF r1=t.mapRect(r);   	//使用t转换r的坐标。
  QLineF n1=t.map(n);     		//使用t转换n的坐标
  //n1也可使用如下等效语句创建,更简洁
  
  //QLineF n1=n*t;   			//注意t*n是错误的
  pr.drawRect(r1);	
  pr.drawLine(n1);//绘制转换后的图形
}   	

在这里插入图片描述

示例12.23:使用变换矩阵计算变换后的坐标值(见图12-59)
void paintEvent(QPaintEvent *e)
{
  QPainter pr(this);    QBrush bs(QColor(1,111,1));    pr.setBrush(bs);
  QRect r(0,55,22,55);
  pr.drawRect(r);
  QTransform t;    t.translate(50,0);    t.rotate(-60);
  QPolygon g1=t.mapToPolygon(r);    pr.drawPolygon(g1);
  qDebug()<

在这里插入图片描述

你可能感兴趣的:(Qt)