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

计算圆弧的起始角度、终止角度和矩形信息并使用drawArc绘制圆弧

Qt中常用绘制圆弧的库函数:

//函数原型
void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)

Qt规定1°约占16个像素,比如一个完整的圆等于360度,对应的像素角度就是 5760度(16 * 360)。

正值的角度表示逆时针方向,而负值的角度表示顺时针方向。因此,如果你指定正值的 startAngle 和 spanAngle,那么绘制的弧形将是逆时针方向的;如果是负值,那么绘制的弧形将是顺时针方向的。0度位于时钟的 3 点钟位置。这意味着,如果 startAngle 为零,弧形的起始点将位于圆的最右侧,然后按照逆时针方向绘制。

例如:

QRectF rectangle(10.0, 20.0, 80.0, 60.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;QPainter painter(this);
painter.drawArc(rectangle, startAngle, spanAngle);

计算drawArc函数所需的startAngle,spanAngle和rectangle

自定义复数类,用于计算参数信息的时候使用
//ComplexNum.h
class ComplexNum
{
public:ComplexNum();ComplexNum(double a, double b);public://复数的四则运算ComplexNum operator +(const ComplexNum& num);ComplexNum operator -(const ComplexNum& num);ComplexNum operator *(const ComplexNum& num);ComplexNum operator /(const ComplexNum& num);//其他函数,设置和取模void setComplexNumValue(double a, double b);double getComplexNumMold();double A();double B();private:double a, b;
};//ComplexNum.cpp
ComplexNum::ComplexNum() :a(0), b(0)
{}ComplexNum::ComplexNum(double a, double b) {this->a = a;this->b = b;
}//复数的四则运算
ComplexNum ComplexNum::operator +(const ComplexNum& num) {return ComplexNum(this->a + num.a, this->b + num.b);
}ComplexNum ComplexNum::operator -(const ComplexNum& num) {return ComplexNum(this->a - num.a, this->b - num.b);
}//复数的相乘(a+bi)(c+di)=(ac-bd)+(bc+ad)i两个复数的积仍然是一个复数
ComplexNum ComplexNum::operator *(const ComplexNum& num) {return ComplexNum(this->a * num.a - this->b * num.b, this->b * num.a + this->a * num.b);
}//复数的除法
ComplexNum ComplexNum::operator /(const ComplexNum& num) {if (!num.a && !num.b) {return ComplexNum(a, b);}else {return ComplexNum((a * num.a + b * num.b) / (num.a * num.a + num.b * num.b),(b * num.a - a * num.b) / (num.a * num.a + num.b * num.b));}
}//其他函数,设置和取模
void ComplexNum::setComplexNumValue(double a, double b) {this->a = a;this->b = b;
}double ComplexNum::getComplexNumMold() {return sqrt(a * a + b * b);
}double ComplexNum::A() {return this->a;
}
double ComplexNum::B() {return this->b;
}//定义圆弧信息结构体,计算圆弧信息的函数返回该结构体对象
struct ArcInfo
{double startAngle;double spanAngle;QRectF rectangle;
};//计算圆弧信息的函数
ArcInfo PixelConversionLibrary::CalculateArc(QPointF start, QPointF end, QPointF center, bool isAcw)
{//计算画弧所需的参数有3个:起始角度、夹角、外切矩形double startAngle = 0, spanAngle = 0;QRectF rectangle;//定义起始向量和终止向量QPointF startVector = start - center;QPointF endVector = end - center;//构建两个复数,一个是起点的复数,一个是终点的复数,两者相除即得到旋转子的复数//乘以一个模为1的复数时,不会导致缩放,只会产生旋转,这样的复数就称为旋转子(rotor)//逆时针:*旋转子(cos(θ)+sin(θ)i)   顺时针:*旋转子的共轨复数(cos(θ)-sin(θ)i)//默认逆时针角度为正,顺时针为负//若span角为0,说明弧是一个整圆,spanAngle需修正为360°ComplexNum c1(startVector.x(), startVector.y());ComplexNum c2(endVector.x(), endVector.y());//ComplexNum rotor = c2 / c1;ComplexNum rotor = c1 / c2;if (isAcw) {spanAngle = qAtan2(rotor.B(), rotor.A());if (spanAngle < 0) {spanAngle += 2 * PI;}}else {spanAngle = -qAtan2(-rotor.B(), rotor.A());if (spanAngle > 0) {spanAngle -= 2 * PI;}}if (fabs(spanAngle) < 0.0001)spanAngle = 2 * PI;//计算起始角c1.setComplexNumValue(1, 0);c2.setComplexNumValue(startVector.x(), startVector.y());//rotor = c2 / c1;rotor = c1 / c2;startAngle = qAtan2(rotor.B(), rotor.A());//弧度转角度spanAngle = spanAngle * (180 / PI);startAngle = startAngle * (180 / PI);double r = sqrtf(pow(startVector.x(), 2) + pow(startVector.y(), 2));QPointF upperLeftPointOfRect = QPointF(center.x() - r, center.y() - r);rectangle.setRect(upperLeftPointOfRect.x(), upperLeftPointOfRect.y(), 2 * r, 2 * r);return { startAngle, spanAngle, rectangle };
}//调用
ArcInfo arcInfo = CalculateArc(pixelStartPoint, pixelEndPoint, pixelCenter, true);
painter.drawArc(arcInfo.rectangle, arcInfo.startAngle * 16, arcInfo.spanAngle * 16);

注意,CalculateArc函数的参数传递的必须都是像素值,这样算出的矩形信息才是像素信息,但是算出的角度依然是实际角度,需要乘以16转化为像素角度。

相关文章:

计算圆弧的起始角度、终止角度和矩形信息并使用drawArc绘制圆弧

Qt中常用绘制圆弧的库函数&#xff1a; //函数原型 void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)Qt规定1约占16个像素&#xff0c;比如一个完整的圆等于360度&#xff0c;对应的像素角度就是 5760度&#xff08;16 * 360&#xff09;…...

C++ Trie树模版 及模版题 || Trie字符串统计

Trie树&#xff1a;用来高效的存储和查找字符串集合的数据结构。 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 x &#xff1b; Q x 询问一个字符串在集合中出现了多少次。 共有 N 个操作&#xff0c;所有输入的字符串总长度不超过 1…...

Linux基础命令@echo、tail、重定向符

目录 echo概念语法作用演示一演示二 反引号作用 tail概念语法作用不带选项&#xff0c;演示一带选项 -num&#xff0c;演示二带选项 -f &#xff0c; 持续跟踪 重定向符概念作用覆盖重定向&#xff0c;>演示一演示二 追加重定向&#xff0c;>>演示一演示二 总结 echo …...

uniapp:签字版、绘画板 插件l-signature

官方网站&#xff1a;LimeUi - 多端uniapp组件库 使用步骤&#xff1a; 1、首先从插件市场将代码下载到项目 海报画板 - DCloud 插件市场 2、下载后&#xff0c;在项目中的uni_modules目录&#xff08;uni_modules优点&#xff1a;不需要import引入&#xff0c;还可以快捷更新…...

Python Pillow(PIL)库的用法介绍

Python的Pillow库&#xff08;PIL&#xff09;是一个强大的图像处理库&#xff0c;可以用来进行图像的读取、编辑、处理和保存等操作。下面是一些Pillow库的基本用法介绍&#xff1a; 安装Pillow库&#xff1a; 在命令行中输入以下命令即可安装Pillow库&#xff1a; 复制代码 p…...

uniapp 【专题详解 -- 时间】云数据库时间类型设计,时间生成、时间格式化渲染(uni-dateformat 组件的使用)

云数据表的时间类型设计 推荐使用时间戳 timestamp "createTime": {"bsonType": "timestamp","label": "创建时间&#xff1a;" }时间生成 获取当前时间 Date.now() .add({createTime: Date.now() })时间格式化渲染 下载安…...

k8s之flink的几种创建方式

在此之前需要部署一下私人docker仓库&#xff0c;教程搭建 Docker 镜像仓库 注意&#xff1a;每台节点的daemon.json都需要配置"insecure-registries": ["http://主机IP:8080"] 并重启 一、session 模式 Session 模式是指在 Kubernetes 上启动一个共享的…...

应用OpenCV绘制箭头

绘制箭头函数 方法&#xff1a;函数cv2.arrowedLine( ) 语法格式&#xff1a;cv2.arrowedLine(img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]]) 参数说明&#xff1a; img&#xff1a;要画的直线所在的图像&#xff0c;也称为画布。。 pt1&#x…...

信息学奥赛一本通1032:大象喝水查

1032&#xff1a;大象喝水查 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 104347 通过数: 64726 【题目描述】 一只大象口渴了&#xff0c;要喝20升水才能解渴&#xff0c;但现在只有一个深h厘米&#xff0c;底面半径为r厘米的小圆桶(h和r都是整数)。问大象至少…...

聊聊jvm的direct buffer统计

序 本文主要研究一下jvm的direct buffer统计 spring boot metrics jvm.memory.used {"name": "jvm.memory.used","description": "The amount of used memory","baseUnit": "bytes","measurements"…...

C/C++ 位段

目录 什么是位段&#xff1f; 位段的内存分配 位段的跨平台问题 什么是位段&#xff1f; 位段的声明与结构是类似的&#xff0c;但是有两个不同&#xff1a; 位段的成员必须是 int、unsigned int 或signed int 等整型家族。位段的成员名后边有一个冒号和一个数字 这是一个…...

Peter算法小课堂—树的应用

开篇先给大家讲个东西&#xff0c;叫vector&#xff0c;有老师称之为“向量”&#xff0c;当然与数学中的向量不一样啊&#xff0c;所以我要称之为“长度可变的数组” vector 头文件&#xff1a;#include <vector> 用法&#xff1a;vector<int> d; 尾部增加元素…...

FineBI:简介

1 介绍 FineBI 是帆软软件有限公司推出的一款商业智能&#xff08;Business Intelligence&#xff09;产品。 FineBI 是定位于自助大数据分析的 BI 工具&#xff0c;能够帮助企业的业务人员和数据分析师&#xff0c;开展以问题导向的探索式分析。 2 现阶段数据分析弊端 现阶…...

原神单机版【完全无脑搭建】⭐纯单机⭐*稳定版*

版本介绍 版本3.7稳定版【过分追新并不稳&#xff0c;合理才完美】 独家原神&#xff0c;游戏内自带剧情任务&#xff0c;完美仿官&#xff0c;一比一完美复制&#xff01; 已经拥有完美剧情、任务、副本、卡池、深渊、全物品、和全部功能和皮肤。 送&#xff1a;GM全套工具…...

用通俗易懂的方式讲解:万字长文带你入门大模型

告别2023&#xff0c;迎接2024。大模型技术已成为业界关注焦点&#xff0c;你是否也渴望掌握这一领域却又不知从何学起&#xff1f; 本篇文章将特别针对入门新手&#xff0c;以浅显易懂的方式梳理大模型的发展历程、核心网络结构以及数据微调等关键技术。 如果你在阅读中收获…...

Invalid options in vue.config.js: “plugins“ is not allowed

项目场景&#xff1a; 安装并配置elementPlus报错。 问题描述 "plugins" is not allowed. plugins不被允许。参考官网修改配置文件vue.config.js。 解决方案&#xff1a; const AutoImport require(unplugin-auto-import/webpack) const Components require(un…...

四、C语言中的数组:数组的创建与初始化

其实在之前的学习中我们已经或多或少接触到了数组&#xff0c;有关scanf()的安全用法中我们提到了如何避免数组溢出的问题&#xff0c;详情可以查看二、C语言数据类型与变量&#xff08;scanf和printf (4&#xff09;完) 这一章我们将详细学习数组在C语言中的应用 1.数组的概…...

html5中各标签的语法格式总结以及属性值说明

有关闭标签的元素 a元素 <a href"" target"" title""></a>表格相关元素 table元素&#xff1a;表格标签caption元素&#xff1a;表头thead元素tbody元素&#xff1a;表格主体元素tfoot元素th元素tr元素&#xff1a;行标签td元素&…...

力扣(leetcode)第412题Fizz Buzz(Python)

412.Fizz Buzz 题目链接&#xff1a;412.Fizz Buzz 给你一个整数 n &#xff0c;找出从 1 到 n 各个整数的 Fizz Buzz 表示&#xff0c;并用字符串数组 answer&#xff08;下标从 1 开始&#xff09;返回结果&#xff0c;其中&#xff1a; answer[i] “FizzBuzz” 如果 i 同…...

苦学golang半年,写了一款web服务器

苦学golang半年&#xff0c;写了一款web服务器 文章目录 苦学golang半年&#xff0c;写了一款web服务器example 项目地址&#xff1a;https://github.com/fengyuan-liang/jet-web-fasthttp 可以的话&#xff0c;请star支持一下&#x1f642; 苦学golang半年&#xff0c;写了一款…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...