转自:http://blog.sina.com.cn/s/blog_67cf08270100ww0p.html

一、坐标系简介。

Qt中每一个窗口都有一个坐标系,默认的,窗口左上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,然后以像素为单位增减。

例如:

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.setBrush(Qt::red);

painter.drawRect(0,0,100,100);

painter.setBrush(Qt::yellow);

painter.drawRect(-50,-50,100,100);

}

我们先在原点(0,0)绘制了一个长宽都是100像素的红色矩形,又在(-50,-50)点绘制了一个同样大小的黄色矩形。可以看到,我们只能看到黄色矩形的一部分。效果如下图。

二、坐标系变换。

坐标系变换是利用变换矩阵来进行的,我们可以利用QTransform类来设置变换矩阵,因为一般我们不需要进行更改,所以这里不在涉及。下面我们只是对坐标系的平移,缩放,旋转,扭曲等应用进行介绍。

1.利用translate()函数进行平移变换。

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.setBrush(Qt::yellow);

painter.drawRect(0,0,50,50);

painter.translate(100,100); //将点(100,100)设为原点

painter.setBrush(Qt::red);

painter.drawRect(0,0,50,50);

painter.translate(-100,-100);

painter.drawLine(0,0,20,20);

}

效果如下。

这里将(100,100)点作为了原点,所以此时(100,100)就是(0,0)点,以前的(0,0)点就是

(-100,-100)点。要想使原来的(0,0)点重新成为原点,就是将(-100,-100)设为原点。


2.利用scale()函数进行比例变换,实现缩放效果。

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.setBrush(Qt::yellow);

painter.drawRect(0,0,100,100);

painter.scale(2,2); //放大两倍

painter.setBrush(Qt::red);

painter.drawRect(50,50,50,50);

}

效果如下。

可以看到,painter.scale(2,2),是将横纵坐标都扩大了两倍,现在的(50,50)点就相当于以前的

(100,100)点。


3.利用shear()函数就行扭曲变换。

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.setBrush(Qt::yellow);

painter.drawRect(0,0,50,50);

painter.shear(0,1); //纵向扭曲变形
   
painter.setBrush(Qt::red);

painter.drawRect(50,0,50,50);

}

效果如下。

这里,painter.shear(0,1),是对纵向进行扭曲,0表示不扭曲,当将第一个0更改时就会对横行进行扭曲,关于扭曲变换到底是什么效果,你观察一下是很容易发现的。


4.利用rotate()函数进行比例变换,实现缩放效果。

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.drawLine(0,0,100,0);

painter.rotate(30); //以原点为中心,顺时针旋转30度
   
painter.drawLine(0,0,100,0);

painter.translate(100,100);

painter.rotate(30);

painter.drawLine(0,0,100,0);

}

效果如下。

因为默认的rotate()函数是以原点为中心进行顺时针旋转的,所以我们要想使其以其他点为中心进行旋转,就要先进行原点的变换。这里的painter.translate(100,100)将(100,100)设置为新的原点,想让直线以其为中心进行旋转,可是你已经发现效果并非如此。是什么原因呢?我们添加一条语句,如下:

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.drawLine(0,0,100,0);

painter.rotate(30); //以原点为中心,顺时针旋转30度

painter.drawLine(0,0,100,0);

painter.rotate(-30);

painter.translate(100,100);

painter.rotate(30);

painter.drawLine(0,0,100,0);

}

效果如下。

这时就是我们想要的效果了。我们加的一句代码为painter.rotate(-30),这是因为前面已经将坐标旋转了30度,我们需要将其再旋转回去,才能是以前正常的坐标系统。不光这个函数如此,这里介绍的这几个函数均如此,所以很容易出错。下面我们将利用两个函数来很好的解决这个问题。

三、坐标系状态的保护。

我们可以先利用save()函数来保存坐标系现在的状态,然后进行变换操作,操作完之后,再用restore()函数将以前的坐标系状态恢复,其实就是一个入栈和出栈的操作。

例如:

void Dialog::paintEvent(QPaintEvent *)

{

QPainter
painter(this);

painter.save(); //保存坐标系状态
   
painter.translate(100,100);

painter.drawLine(0,0,50,50);

painter.restore(); //恢复以前的坐标系状态

painter.drawLine(0,0,50,50);

}

效果如下。

利用好这两个函数,可以实现快速的坐标系切换,绘制出不同的图形。

【转】QPainter中坐标系变换问题的更多相关文章

  1. QPainter的坐标系系统的转换

    声明:本文原创于yafeilinux的百度博客,http://hi.baidu.com/yafeilinux 转载请注明出处. 我看了这篇文章很好很容易理解.如果看了Qt助手之后更加的形象. 前面一节 ...

  2. 5. svg学习笔记-坐标系变换

    之前我们编写图形元素的时候,编写好了位置大小就是固定的,通过坐标系变换,可以移动缩放,旋转图形,但必须声明的是,进行变换时是图形相对于坐标系的变化,就是图形是不发生变化的,而是坐标系发生了变化,比如缩 ...

  3. orocos_kdl学习(一):坐标系变换

    KDL中提供了点(point).坐标系(frame).刚体速度(twist),以及6维力/力矩(wrench)等基本几何元素,具体可以参考 Geometric primitives 文档. Creat ...

  4. 关于Cocos2d-x中坐标系的种类和转换

    注意: 当一个节点有一个子节点的时候,如果移动父节点,子节点也会跟着做相应的移动变化,只要被添加到父节点中,子节点就被绑定了,所以子节点的位置,坐标就会被动地变化. 当一个节点有一个子节点的时候,如果 ...

  5. BZOJ3210: 花神的浇花集会(坐标系变换)

    题面 传送门 题解 坐标系变换把切比雪夫距离转化为曼哈顿距离 那么对于所有的\(x\)坐标中,肯定是中位数最优了,\(y\)坐标同理 然而有可能这个新的点不合法,也就是说不存在\((x+y,x-y)\ ...

  6. OSG数学基础:坐标系变换

    三维实体对象需要经过一系列的坐标变换才能正确.真实地显示在屏幕上.在一个场景中,当读者对场景中的物体进行各种变换及相关操作时,坐标系变换是非常频繁的. 坐标系变换通常包括:世界坐标系-物体坐标系变换. ...

  7. ROS Learning-014 learning_tf(编程) 坐标系变换(tf)广播员 (Python版)

    ROS Indigo learning_tf-01 坐标系变换(tf)广播员 (Python版) 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu ...

  8. 关于CSS3中transform变换的小坑

    2017年6月30日15:05:46 今天在写一个demo的时候,发现CSS3中transform变换的一个特性. 首先,我先描述一下我发现的情况(问题再现): <div class=" ...

  9. opengl中场景变换|2D与3D互转换(转)

    opengl中场景变换|2D与3D互转换 我们生活在一个三维的世界——如果要观察一个物体,我们可以: 1.从不同的位置去观察它.(视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我 ...

随机推荐

  1. 2018-2019-2 20175332-实验一《Java开发环境的熟悉》实验报告

    一.安装IDEA 1.在官方网站下载IDEA安装包https://www.jetbrains.com/idea/download/#section=windows 2.破解软件,第一次参考博客是:ht ...

  2. python之shutil

    ''' shutil 用来处理 文件 文件夹 压缩包 的模块 ''' import shutil # 拷贝文件内容 shutil.copyfileobj(open('old.xml', 'r'), o ...

  3. Hexo + GitEE 搭建、备份、恢复、多终端

    Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页. Hexo 是使用的比较多的博客框架了,我也尝试自己搭 ...

  4. Elasticsearch 通关教程(三): 索引别名Aliases问题

    业务问题 业务需求是不断变化迭代的,也许我们之前写的某个业务逻辑在下个版本就变化了,我们可能需要修改原来的设计,例如数据库可能需要添加一个字段或删减一个字段,而在搜索中也会发生这件事,即使你认为现在的 ...

  5. 从明面上学习ASP.NET Core

    一.前言     这篇文章就是从能看到地方去学习Core,没有很深奥,也没有很难懂,现在我们开始吧. 二.构建项目,引发思考     创建项目的步骤真的很简单,你要是不会,我真也没法了,我这是创建的M ...

  6. 选择语句--switch

    switch语句 格式: 执行流程 首先计算出表达式的值 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束. 最后,如果所有的case都和表达式的值 ...

  7. springboot 学习进度

    1 hello world --------------ok 主启动程序必须在层次结构的最上面. 2 配置 3.日志 4.Web开发 1)SpringBoot集成JSP的方法 配置applicatio ...

  8. [转帖]Linux中的15个基本‘ls’命令示例

    Linux中的15个基本‘ls’命令示例 https://linux.cn/article-5109-1.html ls -lt 和 ls -ltr 来查看文件新旧顺序. list time rese ...

  9. vue环境的搭建与第一个demo

    参考两个博客 1 2 git.npm和淘宝镜像的安装过程过程省略了,直接开始webpack + vue-cli + 创建demo 首先,在磁盘创建一个文件夹,命名为vue-projects,里面再建一 ...

  10. centos django Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING

    os环境 centos python2.7.5 django1.10.8 class AdminAutoRunTask(View): """ 自动跑外放任务 " ...