赞
踩
QPainter.drawRect(QRectF)绘制图形传入的是世界坐标,而后经过变换矩形变为窗口坐标,最后经过窗口-视口变换变为设备坐标。其中世界坐标系和窗口坐标系都属于逻辑坐标系,设备坐标系属于物理坐标。
世界坐标、窗口坐标和设备坐标
- 世界坐标
世界坐标也叫逻辑坐标,使用的单位叫做逻辑单位,在世界坐标系中的大小与显示设备大小无关,类似于数学中的单位长度。
- 窗口坐标
窗口坐标与世界坐标差在坐标变换上,如translate、rotate、scale、shear等。
- 设备坐标
设备坐标是物理坐标,设备的左上角为原点,向右为x正方向,向下为y轴正方向。显示器中,坐标单位通常为像素,打印机中,坐标单位通常为点。
综上,三个坐标系中,世界坐标系和窗口坐标系是逻辑坐标系,与具体的设备大小没有关系,两者之间相差的是坐标变换
窗口和视口
- 窗口
窗口是窗口坐标系中的矩形框,窗口存在的意义是为了确定显示窗口坐标系中的哪部分区域。
使用painter.setWindow(x,y,w,h)即可设置窗口的大小以及坐标系原点在窗口中的位置。默认情况下窗口与视口大小相同,并且原点都位于左上角。
- 视口
视口是设备环境中的一个矩形框,使用物理坐标,和设备大小密切相关,超出设备外的视口区域不予显示(**需要理解下,超出视口区域,但是没有超出设备外也是可以显示的**)。视口存在的意义是为了将显示的内容显示在物理坐标系中的哪个矩形区域。
使用painter.setViewPort(x,y,w,h)即可设置视口的大小以及视口在物理坐标系中的位置。
世界变换和窗口视口变换
- 世界变换
世界变换的目的是直接对逻辑坐标进行矩阵变换,常见的有translate、scale、rotate、shear。
- 窗口视口变换
用户输入的坐标一定是逻辑坐标,最终用来绘制的一定是经过窗口-视口变换后的视口坐标,也就是设备坐标(物理坐标)。
如果不显示使用setViewPort和setWindow指定视口和窗口大小,默认的窗口和视口坐标原点都是(0,0),窗口和视口大小都是设备的长和宽。若设置了一个,那么未设置的仍然使用默认设置。
QPainter::setWindow 修改了窗口位置和大小(**左上角重新定义了一个数值和长度,切记不是像素,是一个逻辑单位,存在跟视口的换算**)
QPainter::setViewport 修改了视口位置和像素个数(左上角移动到相应位置和像素个数)
窗口和视口变换关系实际上就是一对线性函数:
`X' = aX + b`
`Y' = cY + d`
其中,XY为窗口坐标,X'Y'为视口坐标。距离说明:
如果不显示的用代码指定窗口和视口的大小,默认的窗口和视口坐标原点都是(0,0),大小都是设备的长和宽。用代码指定窗口和视口大小的方式分别为:
setWindow(-300,-300,600,600)// 指定窗口位置和大小
setViewPort(-100,-100,600,600)// 指定视口位置和大小。
窗口和视口的变换关系其实就是一对线性函数。
X'=aX+b;
Y'=cY+d。
其中,a,b,c,d为四个待确定的系数,X、Y是窗口坐标,X'、Y'是视口坐标。a,b,c,d如何确定?在窗口(-300,-300,600,600)中,实际上是指定了窗口的两个坐标,左上角(-300,-300),右下角(300,300);在视口(-100,-100,600,600)中,指定了视口左上角坐标(-100,-100),视口右下角(500,500).根据左上角对应左上角,右下角对应右下角的关系,得到:
x方向有:-100=-300a+b,500=300a+b,解得a=1,b=200;
y方向有:-100=-300c+d,500=300c+d,解得c=1,d=200。
得到关系后再来绘图则是经过该关系变换后的值了。比如painter.drawPoint(0,10),对应x=0,得到x'=0*a+b=200;对应y=10,得到y'=10*c+d=210;即实际上是在显示设备的(200,210)处绘制了一个点
示例:
````
{
ui->graphicsView->scale(0.95,0.95);
painter.save();
painter.setPen(Qt::red);
painter.drawRect(0,0, 200, 200);//可视化视口(红色)
painter.setViewport(0,0, 200, 200);
QPen pen = painter.pen();
pen.setStyle(Qt::DashLine);
pen.setWidth(3);
pen.setColor(Qt::blue);
painter.setPen(pen);
painter.setWindow(-100, -100, 200, 200);
painter.drawRect(-100, -100, 200, 200);//可视化窗口(蓝色)
painter.translate(50, 50);//平移(50,50)
painter.setPen(Qt::black);//绘制两个图形
painter.drawRect(-100, -100, 100, 100);
painter.drawRect(50, 50, 100, 100);
painter.restore();
}
````
![92-698792123.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c82c589f8bf846219e5efce562f1b03c~tplv-k3u1fbpfcp-watermark.image?)
1. 视口setViewport(QRectF)传入的是QWidget的物理坐标,窗口setWindow(QRectF)传入的是逻辑坐标。视口和窗口是线性映射关系,因此蓝框和红色框会重合。
2. 平移translate(50,50)操作,移动的是逻辑坐标系,原来的坐标系原点在蓝色窗口中央,平移后位于图示的红色坐标系。
3. save和restore用于保存和恢复QPainter的变换。
一、窗口和视口
世界坐标系中要显示的区域(通常在观察坐标系内定义)称为窗口。
窗口映射到显示器(设备)上的区域称为视口(或称视区)。
窗口定义显示什么;视口定义在何处显示
如何将窗口内的图形在视口中显示出来呢?
必须经过将窗口到视口的变换处理,这种变换就是观察变换(Viewing Transforma)。
二、观察变换
1、变焦距效果
当窗口变小时,由于视口大小不变,就可以放大图形对象的某一部分,从而观察到在较大的窗口时未显示出的细节。
而当窗口变大,视口不变时,视口内显示的内容不断变小。
类似于照相机的变焦处理。
2、整体缩放效果
当窗口大小不变而视口大小发生变化时,得到整体放缩效果。这种放缩不改变观察对象的内容。
如果把一个固定大小的窗口在一幅大图形上移动,时空不变,会产生什么效果?
漫游效果!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。