当前位置: 首页 > article >正文

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(),其中一种参数形式的函数原型是:

  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(),其函数原型为:

void rotate(qreal angle);

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

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

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

3、缩放

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

void scale(qreal sx,qreal sy);

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

4、状态保存与恢复

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

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

坐标变换绘图实例

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

//画五角星
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");
}


http://www.kler.cn/a/373374.html

相关文章:

  • filebeat+elasticsearch+kibana日志分析
  • Java爬虫:在1688上“照片快递”上传图片
  • Uniswap/v2-core使用及其交易流程
  • C++第4课——swap、switch-case-for循环(含视频讲解)
  • 研究轮腿运动学方案的看法
  • 网络搜索引擎Shodan(2)
  • 外键的作用和用法
  • IPD新产品立项管理的典型问题分析(上)
  • 【JVM 深入了解】JVM 到底包含什么?
  • Pycharm报错:Error:failed to find libmagic. Check your installation
  • 信息学奥赛复赛复习19-CSP-J2023-02公路-贪心算法、向上取整、向下取整
  • C# 支持三种方式实现创建 XML文档
  • 关于Android Studio Koala Feature Drop | 2024.1.2下载不了插件的解决办法
  • PHP反序列化-pikachu
  • JavaEE 多线程第四节 (线程核心操作----线程开始/线程终止)
  • 【机器学习】线性回归模型
  • Linux系统rpm安装MySQL详细操作步骤
  • 19 Docker容器集群网络架构:二、etcd 集群部署
  • 【Java多线程】8 Java 中的并发设计模式
  • 【K8S系列】Kubernetes 中 NodePort 类型的 Service 无法访问的问题【已解决】
  • MySQL(2)【库的操作】
  • python爬虫案例——使用aiohttp模块异步请求网站,利用协程加快爬取速度(17)
  • 数据可视化工具深入学习:Seaborn 与 Plotly 的详细教程
  • Linux驱动开发(1):环境搭建
  • 工厂方法模式与抽象工厂模式
  • 九泰智库 | 医械周刊- Vol.65 | 广州发布首批创新药械产品目录