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");
}
相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00613 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术13 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript