精华内容
下载资源
问答
  • 本资源为Qt绘图基础,世界坐标系转换为逻辑坐标系。世界坐标系原点在视图左上角,本例子通过世界坐标转换,将坐标原点定位在视图中央,Y轴向上,X轴向右,并绘制坐标轴,基于逻辑坐标系下的绘图,可将转换关系函数...
  • Qt 坐标轴控件

    热门讨论 2013-05-07 23:45:15
    该控件继承QWidget, 实现了左右上下四种形式的坐标轴控件。 可以设置固定间隔或自动选择间隔 可以设置最小间隔 开放一个槽来动态调整坐标轴的范围 处理了边缘刻度的显示 /***************************************...
  • Qt 坐标系统

    2020-01-02 19:36:25
    坐标系统 以屏幕的左上角为原点即(0, 0)点,从左向右为x轴正向,从上向下为y轴正向,这整个屏幕的坐标系统就用来定位顶层窗口; 此外,窗口内部也有自己的坐标系统,它依然以左上角作为原点,从左向右为x轴正向,...

    一.坐标系统

    以屏幕的左上角为原点即(0, 0)点,从左向右为x轴正向,从上向下为y轴正向,这整个屏幕的坐标系统就用来定位顶层窗口

    此外,窗口内部也有自己的坐标系统,它依然以左上角作为原点,从左向右为x轴正向,从上向下为y轴正向,原点、x轴、y轴围成的区域叫做Client Area(客户区),在客户区的周围则是标题栏(Windows Title)和边框(Frame)。

    二.坐标分析 

    创建了一个最顶层Widget。 

    #include "widget.h"
    #include <QApplication>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        qDebug()<<"=============窗口属性=============";
        qDebug()<<"w.x() = "<<w.x();
        qDebug()<<"w.y() = "<<w.y();
        qDebug()<<"w.width() = "<<w.width();
        qDebug()<<"w.height() = "<<w.height();
        qDebug()<<"==========Geometry属性============";
        qDebug()<<"w.geometry().x() = "<<w.geometry().x();
        qDebug()<<"w.geometry().y() = "<<w.geometry().y();
        qDebug()<<"w.geometry().width() = "<<w.geometry().width();
        qDebug()<<"w.geometry().height() = "<<w.geometry().height();
        qDebug()<<"==========frameGeometry属性============";
        qDebug()<<"w.frameGeometry().x() = "<<w.frameGeometry().x();
        qDebug()<<"w.frameGeometry().y() = "<<w.frameGeometry().y();
        qDebug()<<"w.frameGeometry().width() = "<<w.frameGeometry().width();
        qDebug()<<"w.frameGeometry().height() = "<<w.frameGeometry().height();
    
        return a.exec();
    }
    

    输出结果:

    结论:

    1.QWidget提供的x,y表示的坐标与frameGeometry().x(),frameGeometry().y()的相同。

    2.geomerty()函数,表示客户区的函数,其长和宽 和 widget的长和宽相同,但是其x、y坐标比widget的x、y坐标大,这就证实上图中的坐标系统。

    3.frameGeometry().width(),frameGeometry().height(),比widget的长和宽要大一些。

    分析2:

    调用move(0,0)方法。使其移动到屏蔽的左上角。以下是我调用move(0,0)方法后,可以明显看见窗口左上角未与屏幕左上角重合,可以自己去试试。

    结论:

    以下是Qt的注释:

    move函数移动的位置其实是它的外框移动的位置。

    调用w.setGeometry(0,0,400,300)方法,可以使客户区x、y坐标与屏幕左上角重合,需要隐藏窗口标题栏。调用以下方法设置窗口隐藏。

    w.setWindowFlags(Qt::FramelessWindowHint)

    三.坐标转换

     在窗口上放了一个pushButton,如图

    如果想要知道pushButton的左上角坐标相对于整个屏幕的坐标,则调用

    QPoint pos = ui->pushButton->pos(); 

    QPoint posLeftUp = w.mapToGlobal(pos);

    如果想要知道pushButton的右下角坐标相对于整个屏幕的坐标,则调用

    QPoint pos = ui->pushButton->pos();

    QPoint pos2;

    pos2.setX(pos.x()+ui->pushButton->width());

    pos2.setY(pos.y()+ui->pushButton->height());

    QPoint posRightDown= w.mapToGlobal(pos2);

    四.坐标变换

    坐标变换、包括平移、旋转、缩放。

    展开全文
  • qt坐标系详细讲解

    热门讨论 2011-10-20 11:42:35
    qt 2d绘图的资料,里面包含了坐标机制,很详细
  • QT坐标系统

    2020-05-19 18:11:17
    Qt中,坐标系可以细分成三类: 相对于屏幕的全局坐标 相对于顶层窗口的窗口坐标 相对于控件的控件坐标 Qt中的三类坐标一般是先获得全局坐标,然后将其转换为另外两类坐标。 如果是顶层窗口为转换对象,则转换成...

    Qt中,坐标系可以细分成三类:

    • 相对于屏幕的全局坐标
    • 相对于顶层窗口的窗口坐标
    • 相对于控件的控件坐标

    Qt中的三类坐标一般是先获得全局坐标,然后将其转换为另外两类坐标。
    如果是顶层窗口为转换对象,则转换成窗口坐标;如果是控件为转换对象,则转换成控件坐标。

    具体实现
    在这里插入图片描述
    然后整个坐标的获取是在鼠标移动事件里面实现的:
    在这里插入图片描述
    接下来是实现代码:

    void MainWindow::mouseMoveEvent(QMouseEvent *event)
    {
        //获得相对于屏幕的坐标
        QPoint sPoint1=event->globalPos();
        qDebug()<<"相对于屏幕坐标1:"<<"("<<sPoint1.rx()<<","<<sPoint1.ry()<<")";
        //获得相对于屏幕的坐标
        QPoint sPoint2=QCursor::pos();
        qDebug()<<"相对于屏幕坐标2:"<<"("<<sPoint2.rx()<<","<<sPoint2.ry()<<")";
        //获得相对于窗口的坐标
        QPoint windowPoint=this->mapFromGlobal(sPoint2);
        qDebug()<<"相对于窗口坐标:"<<"("<<windowPoint.rx()<<","<<windowPoint.ry()<<")";
        //获得相对于控件的坐标
        QPoint widgetPoint=ui->label->mapFromGlobal(sPoint1);
        qDebug()<<"相对于控件坐标:"<<"("<<widgetPoint.rx()<<","<<widgetPoint.ry()<<")";
    }
    

    运行程序,在绿色区域的左上角移动:

    在这里插入图片描述
    获得各类坐标:
    在这里插入图片描述

    展开全文
  •  为了能够使用Qt开发图形绘制软件,首先应该掌握Qt坐标系统。在Qt中,通过QPainter类来控制它的坐标系统。连同QPaintDevice类与QPaintEngine类,QPainter类构成了Qt绘图系统的基础。其中,QPainter用于执行绘图的...
  • Qt坐标

    2019-09-27 18:03:21
    这几天学习QT的2D绘图,可因为坐标系统把我拦住了。不但资料少,而且这些资料都是内容雷同。本来这是件非常简单的事情,却有种越描越黑的感觉。经过几天的折腾,总算是理解了这层关系。现在总结一下,不要让大家再走...

    这几天学习QT的2D绘图,可因为坐标系统把我拦住了。不但资料少,而且这些资料都是内容雷同。本来这是件非常简单的事情,却有种越描越黑的感觉。经过几天的折腾,总算是理解了这层关系。现在总结一下,不要让大家再走冤枉路。

    一、我们为什么要有两种坐标系统?

    谈到QT绘图都会跟你说到好几个坐标系,然后就开始被绕晕了。那为什么会这么啰嗦呢?我们换个角度来想一下我们要在屏幕上显示一个图形,程序需要知道哪些东西?

    首先你得有一个具体的可描述尺寸的对象,比如现在有一个手机150x50mm,或者一个图片800x600像素,又或者一个房子占地30x6米。这是具体的,与显示设备无关的单位。描述这些内容的坐标系称为逻辑坐标系。因为眼睛看不来那么多东西,所以你还会有一个特别关注的地方,比如说一幅上百米的清明上河图,你要是拉远了就可以看到全部,拉近了就只能看到几个人的画像。描述你需要关注的这个部分矩形就是窗口,决定了你需要显示的内容。

    接下来是显示器,这是一个以像素为基本单位进行描述的设备。比如说1024x768分辨率的显示器,或者说一个100x200像素的QWidget。那么描述这种环境的坐标系就是物理坐标系。要正确显示的话,程序需要知道的也是两个方面的东西,你在设备环境的什么地方,以多大的范围给你显示出来。

    先看一会图,再来扯具体的概念性的东西~~ 

    二、概念理解

    1、逻辑坐标与窗口

    逻辑坐标:现实工作中作用的坐标系统称为逻辑坐标,使用的单位称为逻辑单位。比如说一个手机尺寸150*50mm。该系统是与显示设备无关的。比如我们常见的Y轴向上的数学坐标系。
    窗口:逻辑环境中的一小部分,是一个矩形框,使用逻辑单位。可以理解为需要显示在屏幕上的显示范围。比如说一部手机,我要放大只看手机屏幕那一部分,那么手机屏幕这个部分就是窗口。如果我要缩小看放手机的桌子,那桌子范围就是窗口。可理解为需要展示的内容。

    2、设备环境与视口

    设备坐标:显示器、打印机,具体的显示控件等等为设备环境。为了便于理解,以下可用QWidget指代设备环境。它的坐标系为设备坐标系(或物理坐标系)。显示器以像素为单位,打印机以点为单位。原点在左上角,正X轴向右,正Y轴向下,固定不变,不可修改!其X、Y的负半轴为虚设,超出设备的部分无法显示或无法打印图形。不管最终的转换结果如何,最后图形还是要转换成屏幕上最终的像素点上。利用QT的方法取得的坐标值一般就是这个。比如QWidget内部的任一点有它位于QWidget左上角的相对坐标位置和位于整个屏幕的绝对坐标位置。利用鼠标的事件event->pos()得到的坐标值是在QWidget内的相对坐标位置,而event->globalPos()的则是位于整个屏幕的绝对位置。

    视口:设备环境中的一部分,一个矩形框,使用的单位同设备环境相同。设置视口相当于指定在设备的什么地方,以多大的范围完全显示指定的窗口内容。这就好比电视的画中画功能,需要指定一个区域显示内容。

    3、窗口与视口关系

    视口是窗口按比例在显示设备(如QWidget)上的投影。窗口解决内容的问题,视口解决显示的问题。二者结合就定义了这两个坐标系的转换关系。注意,它们仅仅是确定转换关系,并非像画中画功能一样,把显示内容限制在视口范围内。只要显示区域足够大,指定的窗口外的其它内容同样也会显示出来。

    以上的说法可能并不准确,实现的过程是基于坐标原点的偏移运算,但我觉得这样说会显得更容易理解,可以帮助理清它们之间的关系。

    4、默认约定

    a)在不作任何设置的默认情况下逻辑坐标和设备坐标系是重合的,它们的初始值都是原点(0,0)在设备环境(如QWidget)的左上角,范围为设备环境的原始大小。也就是说此时的逻辑坐标的位置和范围与设备环境(如QWidget)的初始值是一样的。,并不是我们熟悉的数学坐标。而是与设备坐标一样倒过来的。如果不加以设定,则你看到的绘图的结果就像下面的美女图那样是倒过来的。

    b)用painter.drawLine等方法绘图的时候,都是以逻辑坐标为准的。包括设定的笔刷宽度,也是用的逻辑坐标值。需要自己转换成实际的像素宽度,比如你设置画笔宽度,你设置为1就一定会以1像素显示出来吗?不一定噢!如下图所示要强制以1像素显示出来就先计算一下1像素所对应的逻辑单位值mmPerPix吧。 这个mmPerPix后面会讲到。

    
     
    1. //创建画笔
    2. QPen FastPen(Qt::yellow, 1*mmPerPix.x(), Qt::DashLine, Qt::RoundCap, Qt::RoundJoin); //1像素宽度显示
    3. QPen CutPen(Qt::green, 2*mmPerPix.x(),Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); //2像素宽度显示

    5、坐标变换

    坐标变换依赖于描述坐标系变换关系的矩阵。也就是常说的齐次坐标矩阵方程。上面提到了三种坐标系统。那么在QPainter类中,也存储了对应的三种坐标转换矩阵。

    
     
    1. painter .transform();
    2. painter .worldTransform();
    3. painter .deviceTransform();

     最后还有一个重要的复合转换矩阵,直接进行逻辑坐标到设备坐标的变换。也就是说直接定义了逻辑坐标点和具体的某个像素对应关系。等一下还会提到。

    painter.combinedTransform()      //复合转换矩阵
     

     QPainter类中,提供了直接操作变换参数的方法,如下面所示。这些变换方法是直接改变世界坐标系的变换矩阵。当然了,不管改变哪层变换关系,最后的结果也是一样的。就好比1*2和2*1的结果是一样的道理。

    
     
    1. painter.translate(); //平移
    2. painter.rotate(); //旋转
    3. painter.scale(); //比例
    4. painter.shear(); //扭曲

     你要是嫌麻烦,或者想直接调用已有的变换关系,那么可以直接把这关系塞进去:

    
     
    1. painter .setMatrix();
    2. painter .setTransform();
    3. painter .setWorldTransform();

     

    三、相关转换代码的实现。

    好了,废话是解决不了问题的。概念再清淅最后还不得回归到代码来解决问题么?更多的其它代码就不贴出来了,大家自行网上查找吧,下面只贴出与问题相关的代码。

    1、设置窗口和视口

    
     
    1. painter .setWindow(10,12,50, -100);
    2. painter .setViewport(13,15,100,200);

    这是基本的设置函数,表示了我在逻辑坐标上的起点(10mm,12mm),宽50mm,高100mm的内容要显示在QWidget起点(13px,15px),宽100px,高200px的位置上,这里有两个特殊情况需要处理。

    a) 把显示区域的坐标转成数学坐标(Y轴向上),只要把高的参数改成负数就行了,比如:

    painter.setWindow(10,12,50,-100);
     

    如果这个也很难理解的话可以用另一个方法解决,看代码

    
     
    1. //代替 painter.setWindow 的另一方法
    2. WinSize.setCoords(MinX,MaxY,MaxX,MinY); //直接输入逻辑坐标系的左上角坐标和右下角坐标

     b)最终的图形显示受窗口和视口变换矩阵同时影响,如果设置不正确则可能出现图形变形的情况。解决方法就是保证窗口的高宽比和视口的高宽比相同。比如上面的50/100与100/200的结果值是相同的,这样则不会变形。最简单的就是设置窗口与视口都为正方形。下面是一段根据窗口比例计算视口高宽的例程。

    
     
    1. //按比例显示全部图形
    2. QRect WinSize; //窗口范围
    3. QRect ViewSize; //视口范围
    4. WinSize.setLeft(MinX); //设置窗口范围
    5. WinSize.setTop(MaxY);
    6. WinSize.setWidth(Width);
    7. WinSize.setHeight(-Height);
    8. int AxisOffset= 20; //视口偏移
    9. if (Width>=Height) //图形横放
    10. {
    11. ViewSize.setWidth(rect().width()-AxisOffset* 2);
    12. ViewSize.setHeight(ViewSize.width()*Height/Width);
    13. }
    14. else
    15. {
    16. ViewSize.setHeight(rect().height()-AxisOffset* 2);
    17. ViewSize.setWidth(ViewSize.height()*Width/Height);
    18. }
    19. //居中显示
    20. ViewSize.moveLeft((rect().width()-ViewSize.width())/ 2);
    21. ViewSize.moveTop((rect().height()-ViewSize.height())/ 2);
    22. painter.setWindow(WinSize);
    23. painter.setViewport(ViewSize);

     2、坐标值互换

    上面提到过,用鼠标的QMouseEvent得到的是设备的底层物理坐标。这个事件中可以得到两种值分别是:

    
     
    1. event->pos();  //QWidget上的绝对坐标  
    2. event->globalPos(); //屏幕上的绝对坐标

     还可以通过QWidget上的函数相互转换:

    
     
    1. mapTo(); //转换成某个QWidget内的坐标
    2. mapToParent(); //转换成在父对象上的坐标
    3. mapToGlobal(); //转换成屏幕绝对坐标

     mapForm的是反向转换,不多说了,自己看图。

    3、转换成逻辑坐标

    然而对于专门画图的我来说,上面几个坐标值对我没什么用。比如用CAD画一个图,我需要知道的是mm这些逻辑坐标而已。那怎么把鼠标当前的位置转换成逻辑坐标呢?用矩阵!刚才提到的painter.combinedTransform()这时就派上用场了。在QTransform类中提供了一个map方法,可以把输入点转换成最后的坐标点。

    QPoint NowDragPos = painter.combinedTransform().map(event->pos());
     

    看到这里,你以为就完了吗?No……No……No…… 忘了告诉你,这个转换都是从逻辑坐标向下转成物理坐标的。所以你把event事件中取得的pos()坐标输进去后会得到一堆不知什么鬼的东西。我明明是要从物理坐标转成逻辑坐标呢,也就是说我要反向转换。好吧,QTransform还提供了一种方法inverted()可以返回该变换的逆矩阵。正确的做法是 :

    QPoint NowDragPos = painter.combinedTransform().inverted().map(event->pos());
     

     这个时候就从像素点返回了逻辑坐标点了。还有一件事需要提醒下,在每次的paintEvent事件中,这些矩阵都是恢复为默认值的,所以你需要在类中定义一个QTransform对象来保存这种变换关系以便随时调用。

    ViewToWinTrans=painter.combinedTransform().inverted()();   //保存当前变换的逆矩阵
     

     4、精度控制

     刚才只是用到了QTransform类中map方法的一个重载,用于QPoint的转换。在QTransform中还提供了多种类型的变换,比如QRect。对于QPoint你懂的,xy坐标是int值。对于我这要求严格的来说远远不够用。那就可以用下面这两个重载。

    
     
    1. void QTransform:: map(qreal x, qreal y, qreal *tx, qreal *ty) const
    2. QPointF QTransform:: map( const QPointF &p) const

    5、最后上个效果图吧,在鼠标移动过程中返回该鼠标在逻辑坐标系上的位置,不要在意误差哈。

    6、准确返回每像素对应的逻辑坐标值

    上面说到画笔时提到了mmPerPix这个变量,QT没有直接提供这个方法返回。好吧,自己动手。原理也很简单,直接返回一条1像素的直线长度不就可以了吗?看下面的代码:

    
     
    1. ViewToWinTrans=painter.combinedTransform().inverted(); //保存当前变换的逆矩阵,即每像素的逻辑尺寸
    2. QLineF LineXY(0,0,1,1);
    3. LineXY=ViewToWinTrans. map(LineXY);
    4. mmPerPix.setX(LineXY.dx());
    5. mmPerPix.setY(LineXY.dy());

    7、关于绘图速度

    如果你需要绘制的图形线段非常多,那可能会造成一点卡滞。因为经测试后发现,设置画笔宽度后会大大增加绘图时间。如果把画笔宽度设为0,则默认以1像素去绘图,此时画图速度飞快。原因我也不情楚,希望有知道的大神提点一下原因和解决方法。当然也不是没有办法。给个效果图,速度还是可以的。当然了,这个跟电脑配置也有关系,下面也把我的配置贴出来给大家参考一下。至少对于我来说,这个效率不会比所谓的OpenGL差了。所以说如果觉得绘图速度慢的要好好优化一下程序了。

    四、最后的话

    为了这个坐标转换,花了我不少时间,本来是挺简单的一个事情,却搞得好像很复杂一样。技术就是一层纸,捅破了也就没什么了。刚学QT不久,也是第一次发贴,写得不好的地方希望大家多多包含。有错误的地方还请指出,谢谢!

    修改于:2018-11-24

    展开全文
  • Qt绘制坐标

    2017-09-24 02:43:04
    主要是纯Qt绘图,绘制RT数据,支持框选局部放大查看 也可以进行多通道数据显示,在代码基础上可拓展性比较强。
  • Qt坐标系统之坐标变换矩阵(QTransform类)

    万次阅读 多人点赞 2018-10-21 05:33:34
    Qt坐标变换之坐标变换矩阵(QTransform类) 若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可...

    Qt坐标系统之坐标变换矩阵(QTransform类)

    本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

    本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
    https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
    《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

    若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

    注:本小节需要一些数学知识和计算机图形学方面的知识
    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);
        pr.translate(50,10);		pr.drawRect(r);  	//变换1:平移(50,10)
    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()<<t;		//输出的矩阵为
    					//(11=0.5,12=-1.73205,13=0,21=0.866025,22=1,23=0,31=100,32=60,33=1)
    					//其中11表示第1行1列,12表示第一行2列
        pr.restore();     							//恢复状态,此时坐标系位于变换1处。
    pr.translate(100,0);    pr.drawRect(r);   		//变换3:平移(100,0)
    //变换4:平移(50,0),逆时针旋转60度,缩放2(Y向倍),注意与变换2的顺序。
        pr.translate(50,0);    pr.rotate(-60);    pr.scale(1,2);    pr.drawRect(r);
        pr.resetTransform();   						//重置为初始状态
        pr.translate(200,50);   pr.drawRect(r);}		//变换5:平移(200,50);
    

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

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

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

    1、QPainter类中与QTransform类有关的函数如下
    在这里插入图片描述

    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()<<t;				//输出内容为:QTransform(type=TxRotate,
    // 11=0.5 12=-0.866025 13=0 21=0.866025 22=0.5 23=0 31=20 32=0 33=1)
    pr.drawRect(r);    			//绘制矩形
    //变换2(缩放)
        QTransform t1;    		t1.setMatrix(1,0,0,0,2,0,0,0,1);  //Y方向放大两倍。
        pr.setTransform(t1);    pr.drawRect(r);
    //变换3(平移、旋转、缩放)
    t1=t1*t;    				//使用QTransform重载的*运算符进行矩阵乘运算,此时t1的变换如下:
                				//首先向X方向平移20,再逆时针旋转60度,最后把Y轴方向放大两倍。
    pr.setTransform(t1);  
    qDebug()<<t1;      			//输出内容为:QTransform(type=TxShear,
                          			// 11=0.5 12=-0.866025 13=0 21=1.73205 22=1 23=0 31=20 32=0 33=1)
        pr.drawRect(r);
        t1.reset();        			//重置矩阵为单位矩阵。
        pr.setTransform(t1);  		//变换矩阵的值更改后需要使用QPainter重新设置变换矩阵,
    qDebug()<<t1;     			//输出内容为:QTransform(type=TxNone, 
    //11=1 12=0 13=0 21=0 22=1 23=0 31=0 32=0 33=1)    
    pr.drawRect(r);}
    

    在这里插入图片描述

    示例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()<<t;    qDebug()<<g1;}
    

    在这里插入图片描述

    本文作者:黄邦勇帅(原名:黄勇)

    在这里插入图片描述

    展开全文
  • Qt画图5-----Qt坐标系统

    千次阅读 2018-04-22 14:22:11
    在经历过实际操作,以及前面一节中我们见到的那个translate()函数之后,我们可以详细了解下 Qt坐标系统了。泛泛而谈坐标系统,有时候会觉得枯燥无味,难以理解,好在现在我们已经有了基础。 坐标系统是由...
  •  为了能够使用Qt开发图形绘制软件,首先应该掌握Qt坐标系统。在Qt中,通过QPainter类来控制它的坐标系统。连同QPaintDevice类与QPaintEngine类,QPainter类构成了Qt绘图系统的基础。其中,QPainter用于执行绘图的...
  • QT 坐标系统理解

    万次阅读 多人点赞 2016-12-09 11:45:58
    这几天学习QT的2D绘图,可因为坐标系统把我拦住了。不但资料少,而且这些资料都是内容雷同。本来这是件非常简单的事情,却有种越描越黑的感觉。经过几天的折腾,总算是理解了这层关系。现在总结一下,不要让大家再走...
  • Qt坐标系统

    千次阅读 2018-07-11 16:20:01
    Qt坐标系统是由QPainter类控制的,而QPainter是在绘图设备上进行绘制的。一个绘图设备的默认坐标系统中,原点(0,0)在其左上角,x坐标向右增长,y坐标向下增长。 QPainter的逻辑坐标与绘图设备的物理坐标之间的...
  • 没有复杂的变换,简单转化窗口坐标系,即可按我们正常熟知的... m_pPainter.setBrush(Qt::yellow); m_pPainter.drawRect(0, 0, 50, 50); m_pPainter.translate(100, 100); //将点(100,100)设为原点 m_pPainter...
  • QT坐标系折线图

    2018-01-02 15:06:05
    QT使用QPainter画坐标系折线图,图中可显示所有数据的最大值,最小值,以及平均值,
  • QT坐标转换——旋转

    千次阅读 2018-11-10 15:09:00
    关于图元的旋转问题,之前也查询了许多资料,都是利用rotate()函数进行操作的。 1.voidQPainter::rotate(qrealangle): 以原点为旋转中心,顺时针... 实现绕坐标轴的旋转,两个坐标在分别为:XAxis,YAxis。 ...
  • 2、新建控件的Qt类,父类是QWidget,带ui的,Control.h #ifndef CONTROL_H #define CONTROL_H #include <QWidget> namespace Ui { class Control; } class Control : public QWidg...
  • QT坐标系统.pdf

    2021-09-14 13:36:32
    QT坐标系统.pdf
  • Qt坐标系统之窗口/视口变换原理

    千次阅读 2018-10-18 09:39:31
    Qt坐标变换原理之窗口/视口变换原理 若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解。 需要用到...
  • 之前写的代码是对图元的翻转,其本身坐标发生了改变,为了改善这个问题,可以对整个视图进行翻转,从而保证图元坐标不发生变化。 QTransform transform; transform.rotate(180,Qt::XAxis);//视图绕x轴旋转180度 ...
  • 代码实现:读取图片,显示图像,获取图片坐标及像素值进行显示(vs2013+qt5.3.0 x64环境)
  • 用于图像标注工具的坐标点拖动小例子,具体的图像标志请参考Qt C++版深度学习图像标注工具 - Alex_XT的博客 - CSDN博客 https://blog.csdn.net/u011463646/article/details/88628322
  • qt坐标系统与布局的简单入门

    千次阅读 2016-04-27 10:31:28
    qt坐标系统 qt坐标系统比较简单 button.setGeometry(20,20,100,100); 上面的代码把按钮显示为父窗口的20,20处宽度为100,高度为100 接下去是布局 qt里面布局需要加入这个头文件。 qt里面垂直布局 qt里面的垂直布局...
  • QT开发(十五)——QT坐标系统一、QT坐标系简介 Qt中每一个窗口都有一个坐标系,默认窗口左上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,以...
  • 大地测量课程作业,布尔沙模型的坐标转换,以及空间和大地坐标之间的转换,用Qt在mingw下写的,有啥问题私我,新人哪做的不好求轻喷和关照谢谢
  • Win32消息的屏幕坐标如何转换Qt坐标 偶尔一些情况,需要将Win32 API获取到的鼠标位置转换到Qt的窗口坐标中,常见的方法是除以当前窗口的缩放(QPaintDevice::devicePixelRatioF或者其他),这样做是不准确的,只适合...
  • QT 坐标系统

    千次阅读 2014-11-26 15:34:30
    一个绘图设备的默认坐标系统中原点(0,0)在其左上角,x坐标向右增长,y坐标向下增长。 逻辑坐标与绘图设备的物理坐标之间的映射由QPainter的变换矩阵、视口和窗口来处理的。逻辑坐标和物理坐标默认是一致的。 一. ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,682
精华内容 8,672
关键字:

QT坐标