Qt坐标变换详解

文章目录

  • Qt坐标变换详解
    • 初始化 QPainter
    • 设置画笔和字体
    • 坐标平移
    • 坐标旋转
    • 坐标扭转
    • 坐标缩放
    • 保存和恢复坐标状态
    • 复位所有的坐标变换
    • 综合示例:绘制五角星
      • 解释
    • 总结

Qt坐标变换详解

在图形编程中,坐标变换是非常重要的概念,它可以帮助我们方便地进行平移、旋转、缩放和剪切等操作。在Qt中,QPainter 提供了丰富的坐标变换功能,使得复杂的图形操作变得简单。本文将通过具体的示例代码,详细讲解Qt中常用的坐标变换方法。

初始化 QPainter

在开始绘制之前,我们需要创建一个 QPainter 对象并启用抗锯齿功能,以提高绘图的质量。以下代码展示了如何初始化 QPainter

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

通过设置抗锯齿和文本抗锯齿,可以使绘制的图形和文字更加平滑,避免锯齿现象。Antialiasing 主要用于平滑图形边缘,而 TextAntialiasing 则用于平滑文本的边缘。

设置画笔和字体

在绘制图形和文字之前,需要设置画笔和字体的属性。以下代码展示了如何设置画笔和字体:

QPen pen;
pen.setWidth(4);
pen.setColor(Qt::red);
painter.setPen(pen);QFont font;
font.setPointSize(20);
painter.setFont(font);

这里我们创建了一个 QPen 对象,并将其宽度设置为4,颜色设置为红色。然后将该画笔应用于 QPainter。同时,我们创建了一个 QFont 对象,并将其大小设置为20,然后将该字体应用于 QPainter。这使得接下来绘制的图形使用红色线条,并且绘制的文本使用大小为20的字体。

坐标平移

坐标平移是将绘图的原点从一个位置移动到另一个位置。以下代码展示了如何使用 translate() 方法进行坐标平移:

QRect imageRect(100, 100, 400, 300);
QImage image(":/JINGMAO.jpg");
painter.drawImage(imageRect, image);// 坐标平移
painter.translate(400, 300);
painter.drawImage(imageRect, image);

在这段代码中,第一次绘制图片时使用了原始坐标 (100, 100)(500, 400) 的矩形区域。然后,使用 painter.translate(400, 300) 将坐标系平移到 (400, 300) 位置,再次绘制相同的图片。通过这种方式,图片会被绘制到新的位置 (500, 400)(900, 600)。坐标平移使我们可以方便地改变绘图的位置,而不需要更改具体的绘制代码。

坐标旋转

坐标旋转是将整个坐标系绕原点旋转一定的角度。以下代码展示了如何使用 rotate() 方法进行坐标旋转:

painter.resetTransform(); // 重置变换
painter.drawImage(imageRect, image);// 坐标旋转
painter.rotate(30); // 旋转30度
painter.drawImage(imageRect, image);

在这段代码中,首先绘制了原始图片。然后,使用 painter.rotate(30) 将坐标系顺时针旋转30度,再次绘制相同的图片。通过这种方式,图片会以原点为中心进行旋转。需要注意的是,旋转是以当前坐标系的原点为中心进行的,原点的位置也会随平移操作而改变。旋转操作通常用于需要绘制特定角度的图形或在特定角度绘制文本的场景。

坐标扭转

坐标扭转(剪切)是将坐标系中的网格线进行倾斜。以下代码展示了如何使用 shear() 方法进行坐标扭转:

painter.resetTransform(); // 重置变换
painter.drawImage(imageRect, image);// 坐标扭转
painter.shear(0.1, 0.1); // x方向和y方向各剪切0.1
painter.drawImage(imageRect, image);

在这段代码中,首先绘制了原始图片。然后,使用 painter.shear(0.1, 0.1) 将坐标系的x方向和y方向各剪切0.1,再次绘制相同的图片。通过这种方式,图片会发生倾斜。剪切变换可以用来创建逼真的透视效果或斜体文本效果。剪切操作改变了坐标系的形状,使得水平和垂直方向上的网格线不再平行,从而产生倾斜效果。

坐标缩放

坐标缩放是将坐标系按比例放大或缩小。以下代码展示了如何使用 scale() 方法进行坐标缩放:

painter.resetTransform(); // 重置变换
painter.drawImage(imageRect, image);// 坐标缩放
painter.scale(0.5, 0.5); // 缩小到50%
painter.drawImage(imageRect, image);

在这段代码中,首先绘制了原始图片。然后,使用 painter.scale(0.5, 0.5) 将坐标系缩小到原来的50%,再次绘制相同的图片。通过这种方式,图片会按比例缩小。缩放操作可以用来改变图形或文本的大小,而无需修改其定义。需要注意的是,缩放会同时影响水平和垂直方向,因此可以实现各种比例的放大或缩小效果。

保存和恢复坐标状态

在进行多次复杂的变换时,保存和恢复坐标状态非常有用。以下代码展示了如何使用 save()restore() 方法进行操作:

QRect imageRect(0, 0, 400, 300);
QImage image(":/JINGMAO.jpg");
painter.drawImage(imageRect, image);// 保存坐标状态
painter.save();// 进行变换
painter.shear(0.1, 0.1);
painter.drawImage(imageRect, image);// 恢复坐标状态
painter.restore();
painter.drawImage(imageRect, image);

在这段代码中,首先绘制了原始图片。然后,使用 painter.save() 保存当前的坐标状态。接下来,进行剪切变换并绘制图片。最后,使用 painter.restore() 恢复到保存的坐标状态,再次绘制相同的图片。通过这种方式,可以方便地在复杂变换之间切换,而无需手动恢复每一步变换。保存和恢复坐标状态特别适用于需要在同一绘制操作中应用多种变换的情况。

复位所有的坐标变换

在某些情况下,需要复位所有的坐标变换,使坐标系回到初始状态。以下代码展示了如何使用 resetTransform() 方法复位坐标变换:

painter.resetTransform(); // 复位所有的坐标变换
painter.drawImage(imageRect, image);

在这段代码中,使用 painter.resetTransform() 方法复位所有的坐标变换。通过这种方式,坐标系将回到初始状态,之后的绘制操作将不受之前变换的影响。resetTransform() 方法清除了所有的平移、旋转、缩放和剪切变换,使得坐标系恢复到默认状态。这在需要清除所有变换并重新开始绘制时非常有用。

综合示例:绘制五角星

最后,我们将以上的知识点结合起来,绘制一个五角星。以下代码展示了如何计算五角星的顶点并进行绘制:

qreal r = 200;
qreal PI = 3.14159;
qreal unit = 72 * PI / 180;
QPoint points[5] = {QPoint(r, 0),QPoint(r * cos(unit), -r * sin(unit)),QPoint(r * cos(2 * unit), -r * sin(2 * unit)),QPoint(r * cos(3 * unit), -r * sin(3 * unit)),QPoint(r * cos(4 * unit), -r * sin(4 * unit))
};
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(r * 1.2, r * 1.1);
painter.rotate(-18);
painter.drawPath(starPath);
painter.restore();

解释

  1. 计算五角星顶点:使用三角函数计算五角星的五个顶点坐标。通过将极坐标转换为直角坐标,计算出每个顶点的位置。
  2. 创建路径:使用 QPainterPath 对象定义五角星的路径,并连接各个顶点。moveTo 方法将路径起点移动到第一个顶点,然后使用 lineTo 方法依次连接其他顶点。
  3. 添加文本标签:在每个顶点位置添加相应的文本标签。使用 addText 方法在路径上添加文本,标记每个顶点的位置。
  4. 保存状态并变换坐标系:使用 painter.save() 保存当前坐标状态,使用 painter.translate()painter.rotate() 进行平移和旋转变换。
  5. 绘制五角星并恢复状态:使用 painter.drawPath() 绘制五角星,然后使用 painter.restore() 恢复到保存的坐标状态。

通过以上代码,我们成功绘制了一个红色的五角星,每个顶点上标有相应的数字。利用Qt提供的坐标变换功能,使得绘制复杂图形变得更加简单和直观。

总结

Qt提供了丰富的坐标变换功能,包括平移、旋转、剪切和缩放等,使得图形编程更加灵活和强大。通过 save()restore() 方法,可以方便地管理和切换不同的变换状态。掌握这些坐标变换方法,将极大地提升我们在Qt中进行图形绘制的能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/868202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InvalidVersionSpecError: Invalid version spec: =2.7解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

MATLAB神经网络中的seq2con()

seq2con 源文档解释:Convert sequential vectors to concurrent vectors 源文档例1: p1 {1 4 2} p2 seq2con(p1) 结果: p1 13 cell 数组 {[1]} {[4]} {[2]} p2 11 cell 数组 {13 double} {[1,4,2]} 源文档例2: p…

接口分组:内部调用与第三方调用接口

一套微服务项目,给本项目前端调用的接口和给其他第三方调用的接口,是否应该拆分成两个不同的服务(或网关),还是可以放在一个服务中? 对于一套微服务项目,将给前端调用的接口与给第三方调用的接…

微软Edge浏览器全解析:从速度到安全性的全面体验

微软Edge浏览器,自2015年首次亮相以来,已经成为了浏览器市场上不可忽视的一股力量。它不仅集成了Windows 10的许多原生功能,还在速度和安全性上进行了大量的优化。本文将全面解析微软Edge浏览器的各项特性,带您领略这款浏览器的魅…

idea 默认路径修改

1.查看 idea 的安装路径(右键点击 idea 图标,查看路径 ) “C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin\idea64.exe” 在 bin 目录查看 idea.properties 文件,修改以下四个路径文件 # idea.config.path${user.home}/…

RKNN3588——利用推理YOLOv8推理图片

1. yolov8_test.py import os import cv2 import numpy as np from class_type import CLASSES# 设置对象置信度阈值和非极大值抑制(NMS)阈值。 OBJ_THRESH 0.25 NMS_THRESH 0.45 IMG_SIZE (640, 640)def filter_boxes(boxes, box_confidences, box_…

超高精电容传感器PCAP01调试+LABVIEW数据可视化调试手记

PCAP01超高精电容传感芯片STM32LabView可视化 文章目录 PCAP01超高精电容传感芯片STM32LabView可视化一、PCAP01介绍1.1、PCAP01引脚定义1.2、电容测量1.3、温度测量1.4、PCAP典型测试电路 二、PCAP01的STM32驱动2.1、SPI协议配置2.2、PCAP01浮空电容测量内部温度测量操作流程 …

Java Swing 5种布局管理器基本示例

在Java Swing中,常用的布局管理器有BorderLayout、FlowLayout、GridLayout、BoxLayout和GridBagLayout。最灵活的是GridBagLayout。 基本使用如下, borderlayout, import javax.swing.*; import java.awt.*;public class borderlay {publi…

yum install epel-release 遇到的问题

问题: 安装epel的时候,执行 yum install -y epel-release 报错“Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx86_64&repoos&infrastock error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.…

读人工智能全传06逻辑编程

1. 现代逻辑 1.1. 到了20世纪初,现代逻辑的基本框架已经大致建立起来,当时确立的逻辑运算系统,直至如今仍然能够支撑数学家几乎所有的逻辑推理工作 1.1.1. 这个系统被称为一阶逻辑,一阶逻辑是数学和推理的通用语言 1.1.2. 这个…

知识的向量表示

1、one-hot表示,空间太大 2、bag词袋模型,无法表示词的语义 3、词的语义由什么决定?词由他的上下文决定?分布式语义 4、CBow,通过前面几个词和后面几个词,预测中间几个词 5、skip-gram,通过…

Matlab协方差矩阵分解法生成随机场

Matlab协方差矩阵分解法生成随机场 相关系数矩阵 % function outcohesion(x,y,mu,theta) % end % xyload(F:\Research-OUC\基于机器许学习模型的海底斜坡可靠度研究\基于comsol的斜坡稳定性分析\comsol网格操作\grid_operate-matlab.mphtxt); % xxy(:,1); % yxy(:,2); Xlinspac…

游戏开发面试题1

C#,泛型、反射? C# 泛型是指可以让开发者在声明和使用类和方法时指定类型参数的编程技术。它可以减少代码重复,使程序的可维护性更高,并且能够更好地管理内存。 反射是指.NET程序集中类、方法、属性和字段的可编程性。它允许在不知…

等保测评推动哈尔滨数字化转型中的安全保障

在数字经济的浪潮下,哈尔滨作为东北老工业基地的核心城市,正积极推动数字化转型,以创新技术驱动产业升级和经济发展。网络安全等级保护测评(简称“等保测评”)作为国家网络安全战略的重要组成部分,为哈尔滨…

泛型(generics)

目录 一、泛型概述 二、定义泛型类 三、定义泛型方法 四、List接口中的泛型是如何定义的 五、泛型通配符 六、 泛型通配符的上限和下限 七、可变参数 八、可变参数的使用 九、泛型擦除机制 一、泛型概述 Java泛型是JDK5中引入的一个新特性,提供了编译时类型…

Adobe Premiere Pro 2024 v24.5 (macOS, Windows) - 专业视频编辑软件

Adobe Premiere Pro 2024 v24.5 (macOS, Windows) - 专业视频编辑软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、Lightroom Classic、Media Encoder、Photoshop、Premiere Pro、Adob…

在Ubuntu 16.04上安装和配置Redis的方法

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 Redis 是一个内存中的键值存储,以其灵活性、性能和广泛的语言支持而闻名。在本指南中,我们将演示如何在 U…

【Selenium配置】WebDriver安装浏览器驱动(ChromeEdge)

【Selenium配置】WebDriver安装浏览器驱动(Chrome&Edge) 文章目录 【Selenium配置】WebDriver安装浏览器驱动(Chrome&Edge)Chrome确认Chrome版本下载对应driver把解压后的chromedriver文件放在chrome安装目录下&#xff0…

算法简介:什么是算法?——定义、历史与应用详解

引言 在现代计算机科学中,算法是一个核心概念。无论是编程还是数据分析,算法都扮演着至关重要的角色。在这篇博客中,我们将深入探讨算法的定义、历史背景以及它在计算机科学中的地位和实际应用。 什么是算法? 算法是解决特定问题…

Linux 定期自动修改密码,防止过期

背景 😂 Jenkins 中使用 ssh 密码登录,实现项目前端部署。 😂 ssh 账号(假设叫做 ft)每隔三个月就会过期,就会导致前端部署报错,提示“Your password is expired” 😂 每次修改密码,需要申请权限,审批,耗时较长。=》希望自动修改密码,防止过期 分析 1、模拟生…