Qt 坐标系统与坐标变换

Qt 坐标系统与坐标变换

坐标变换函数

QPainter坐标变换相关函数

分组 函数原型 功能
坐标变换 void translate(qreal dx,qreal dy) 坐标系统一定的偏移量,坐标原点平移到新的点
坐标变换 void rotate(qreal angle) 坐标系统顺时针旋转-一个角度
坐标变换 void scale(qreal sx,qreal sy) 坐标系统缩放
坐标变换 void shear(qrael sh,qreal sy) 坐标系统做扭转变换
状态保存与恢复 void save() 保存painter当前的状态,就是将当前状态压入栈
状态保存与恢复 void restore() 恢复上一次状态,就是从堆栈中弹出上次的状态
状态保存与恢复 void resetTransform() 复位所有的坐标变换
状态保存与恢复

1、坐标平移

坐标平移函数是translate(),其中一种参数形式的函数原型是:

cpp 复制代码
  void translate(qreal dx,qreal dy);

表示将坐标系统水平方向平移个单位,垂直方向平移个单位,在缺省的坐标系统中,单位就是像素。如果是从原始状态平移(dx,dy),那么平移后的坐标原点就移到了(dx,dy)。

假设一个绘图窗口宽度为300像素,高度为200像素,则其原始坐标系统如图8-10左所示; 若执行平移函数 translate(150,100),则坐标系统水平向右平移150像素,向下平移100像素,平 移后的坐标系统如图8-10右所示,坐标原点在窗口的中心,而左上角的坐标变为(-150,-100), 右下角的坐标变为(150,100)。如此将坐标原点变换到窗口中心在绘制某些图形时是非常方便的。

2、坐标旋转

坐标旋转的函数是rotate(),其函数原型为:

cpp 复制代码
void rotate(qreal angle);

它是将坐标系统绕坐标原点顺时针旋转angle角度,单位是度。当angle为正数时是顺时针旋 转,为负数时是逆时针旋转。在图8-10右的基础上,若执行rotate(90),则得到图8-11所示的坐标系统。

注意:旋转之后并不改变窗口矩形的实际大小,只是改变了坐标轴的方向。

在图8-11的新坐标系下,窗口左上角的坐标变成了(-100,150),而右下角的坐标变成了(100,-150)。

3、缩放

缩放函数是scale(),其函数原型为:

cpp 复制代码
void scale(qreal sx,qreal sy);

其中,sx,sy分别为横向和纵向缩放比例,比例大于1是放大,小于1是缩小。

4、状态保存与恢复

进行坐标变换时,QPainter内部实际上有一个坐标变换矩阵,用save()保存当前坐标状态,用 restore()恢复上次保存的坐标状态,这两个函数 必须配对使用 , 操作的是一个堆栈对象 。

resetTransform()函数则是复位所有坐标变换操作,恢复原始的坐标系统。

坐标变换绘图实例

(1)绘制3个五角星的程序

创建一个基于QWidget的窗口的应用程序samp8_123,窗体上不放置任何组件。在Widget类的 构造函数和paintEvent()事件中调用MyPaintFiveStar()函数,MyPaintFiveStar()的代码内容如下:

cpp 复制代码
//画五角星
void sample8_123QPainter::MyPaintFiveStar()
{
	QPainter painter(this);//创建QPainter对象

	painter.setRenderHint(QPainter::Antialiasing);//
	painter.setRenderHint(QPainter::TextAntialiasing);//

	//生成五角星的5个顶点的,假设原点在五角星中心
	qreal R = 100;//半径
	const qreal Pi = 3.14159;
	qreal deg = Pi * 72 / 180;//

	//QPoint points[5] = {//针对Qt 5.12.1 编译错误修改,使用<Qtmath>中的函数 qSin(), qCos()
	//	QPoint(R, 0),
	//	QPoint(R*qCos(deg), -R*qSin(deg)),
	//	QPoint(R*qCos(2 * deg), -R*qSin(2 * deg)),
	//	QPoint(R*qCos(3 * deg), -R*qSin(3 * deg)),
	//	QPoint(R*qCos(4 * deg), -R*qSin(4 * deg))
	//};

	QPoint points[5]={ //这些代码在Qt 5.12.1中编译有问题,没有函数std::cos(),std::sin()
	    QPoint(R,0),
	    QPoint(R*std::cos(deg),-R*std::sin(deg)),
	    QPoint(R*std::cos(2*deg),-R*std::sin(2*deg)),
	    QPoint(R*std::cos(3*deg),-R*std::sin(3*deg)),
	    QPoint(R*std::cos(4*deg),-R*std::sin(4*deg))
	};

	//设置字体
	QFont   font;
	font.setPointSize(12);
	font.setBold(true);
	painter.setFont(font);

	//设置画笔
	QPen    penLine;
	penLine.setWidth(2);//线宽 
	penLine.setColor(Qt::blue);//划线颜色 
	//Qt::NoPen,Qt::SolidLine, Qt::DashLine, Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine
	penLine.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
	//Qt::FlatCap, Qt::SquareCap,Qt::RoundCap
	penLine.setCapStyle(Qt::FlatCap);//线端点样式
	//Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin,Qt::SvgMiterJoin
	penLine.setJoinStyle(Qt::BevelJoin);//线的连接点样式
	painter.setPen(penLine);

	//设置画刷
	QBrush  brush;
	brush.setColor(Qt::yellow);//画刷颜色 
	brush.setStyle(Qt::SolidPattern);//画刷填充样式
	painter.setBrush(brush); 

//    QPen    penText;
//    penText.setWidth(2); //线宽
//    penText.setColor(Qt::blue); //划线颜色

	//设计绘制五角星的PainterPath,以便重复使用
	QPainterPath starPath;
	starPath.moveTo(points[0]);
	starPath.lineTo(points[2]);
	starPath.lineTo(points[4]);
	starPath.lineTo(points[1]);
	starPath.lineTo(points[3]); 
	starPath.closeSubpath();//闭合路径,最后一个点与第一个点相连

	starPath.addText(points[0], font, "0"); //显示端点编号
	starPath.addText(points[1], font, "1");
	starPath.addText(points[2], font, "2");
	starPath.addText(points[3], font, "3");
	starPath.addText(points[4], font, "4");


	//绘图
	painter.save(); //保存坐标状态
	painter.translate(100, 120);
	painter.drawPath(starPath); //画星星
	painter.drawText(0, 0, "S1");
	painter.restore(); //恢复坐标状态

	painter.translate(300, 120); //平移
	painter.scale(0.8, 0.8); //缩放
	painter.rotate(90); //顺时针旋转
	painter.drawPath(starPath);//画星星
	painter.drawText(0, 0, "S2");

	painter.resetTransform(); //复位所有坐标变换
	painter.translate(500, 120); //平移
	painter.rotate(-145); //逆时针旋转
	painter.drawPath(starPath);//画星星
	painter.drawText(0, 0, "S3");
}
相关推荐
engchina9 分钟前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it9 分钟前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
诚丞成35 分钟前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++
Smile灬凉城6661 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
lsx2024061 小时前
SQL MID()
开发语言
Dream_Snowar1 小时前
速通Python 第四节——函数
开发语言·python·算法
西猫雷婶1 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
鸿蒙自习室1 小时前
鸿蒙UI开发——组件滤镜效果
开发语言·前端·javascript
言、雲1 小时前
从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
java·开发语言·数据库
汪洪墩2 小时前
【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换
开发语言·javascript·python·ecmascript·webgl·cesium