Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1336718
  • 博文数量: 177
  • 博客积分: 3640
  • 博客等级: 中校
  • 技术积分: 1778
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-27 16:51
文章分类

全部博文(177)

文章存档

2014年(1)

2013年(10)

2012年(3)

2011年(163)

分类: LINUX

2011-05-15 14:00:54

前面一节我们讲解了图片的显示, 其中很多都用到了坐标的变化,这一节我们简单讲一下Qt的坐标系统,其实也还是主要讲上一节的那几个函数。这里我们先讲解一下Qt的坐标系,然后讲解那几 个函数,它们分别是:

translate()函数,进 行平移变换;scale()函数,进行比例变换;rotate()函数,进行旋转变换;shear()函数,进行扭曲变换。

最后介绍两个有用的函数 save()和restore(),利用它们来保存和弹出坐标系的状态,从而实现快速利用几个变换来绘图。

一、坐标系简 介。

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);
}
效果

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

(由于图片复制不了,因此把地址给大家)

http://hi.baidu.com/juanjuan200510/blog/item/54c532ebd16e20e9b2fb950a.html

阅读(5756) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~