QT实现凸凹边形等距缩放

参考:https://blog.csdn.net/weixin_39383896/article/details/99615371和https://blog.csdn.net/qq_15821883/article/details/117421400
在这里插入图片描述

在这里插入图片描述
代码逻辑思路:
1、获取向量AB、BC的坐标。
2、计算向量AB、BC的长度。
3、根据点乘获取cosθ大小。
4、根据cosθ大小判断夹角为钝角还是锐角。
5、如果小于等于90度,根据缩放距离、夹角和等间距求缩放后的点位置。
6、如果大于90度,根据叉积公式判断多边形为凸边形还是凹变形。
7、判断凸凹边形后,根据缩放距离、夹角和等间距求缩放后的点位置。
实现结果:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Qt实现代码:

QVector<QPointF> Widget::calcPoint(const QVector<QPointF> &datas, int sec_dis)
{QVector<double> x;QVector<double> y;int number = datas.size();if (number < 3){return QVector<QPointF>();}for (int i = 0; i < number; ++i){x.append(datas[i].x());y.append(datas[i].y());}QVector<QPointF> points;for (int i = 0; i < number; ++i){// 向量ABdouble x1 = x[i % number] - x[(i - 1 + number) % number];double y1 = y[i % number] - y[(i - 1 + number) % number];// 向量BCdouble x2 = x[i % number] - x[(i + 1)% number];double y2 = y[i % number] - y[(i + 1)% number];// 求线段的长度double d1 = sqrt(x1*x1 + y1 * y1);double d2 = sqrt(x2*x2 + y2 * y2);// 点乘double ab = x1 * x2 + y1 * y2;// cosθ = A * B / (|A| * |B|)double cosA = ab / (d1 * d2);// 求sinAdouble sinA;if (cosA  > 0) // 表示夹角0-90度 锐角{sinA = sqrt(1 - cosA * cosA);double dv1 = sec_dis / sinA;// # 向量V1,V2的坐标double v1_x = (dv1 / d1) * x1;double v1_y = (dv1 / d1) * y1;double v2_x = (dv1 / d2) * x2;double v2_y = (dv1 / d2) * y2;double PiQi_x = v1_x + v2_x;double PiQi_y = v1_y + v2_y;double Qi_x = PiQi_x + x[i];double Qi_y = PiQi_y + y[i];points.append(QPointF(Qi_x, Qi_y));}else if(cosA < 0) // 钝角  钝角分为外钝角和 内钝角{// 判断凹凸点(叉积)double P1P3_x = x[(i + 1) % number] - x[i];double P1P3_y = y[(i + 1) % number] - y[i];double P1P2_x = x[i] - x[(i - 1 + number) % number];double P1P2_y = y[i] - y[(i - 1 + number) % number];double P = (P1P3_y*P1P2_x) - (P1P3_x*P1P2_y);// 为凹if (P < 0){sinA = -sqrt(1 - cosA * cosA);double dv1 = sec_dis / sinA;double v1_x = (dv1 / d1) * x1;double v1_y = (dv1 / d1) * y1;double v2_x = (dv1 / d2) * x2;double v2_y = (dv1 / d2) * y2;double PiQi_x = v1_x + v2_x;double PiQi_y = v1_y + v2_y;double Qi_x = PiQi_x + x[i];double Qi_y = PiQi_y + y[i];points.append(QPointF(Qi_x, Qi_y));}else if (P > 0) // 为凸{sinA = -sqrt(1 - cosA * cosA);double dv1 = -sec_dis / sinA;double v1_x = (dv1 / d1) * x1;double v1_y = (dv1 / d1) * y1;double v2_x = (dv1 / d2) * x2;double v2_y = (dv1 / d2) * y2;double PiQi_x = v1_x + v2_x;double PiQi_y = v1_y + v2_y;double Qi_x = PiQi_x + x[i];double Qi_y = PiQi_y + y[i];points.append(QPointF(Qi_x, Qi_y));}else // error{return QVector<QPointF>();}}else if(cosA == 0){sinA = 1;double dv1 = sec_dis / sinA;double v1_x = (dv1 / d1) * x1;double v1_y = (dv1 / d1) * y1;double v2_x = (dv1 / d2) * x2;double v2_y = (dv1 / d2) * y2;double PiQi_x = v1_x + v2_x;double PiQi_y = v1_y + v2_y;double Qi_x = PiQi_x + x[i];double Qi_y = PiQi_y + y[i];points.append(QPointF(Qi_x, Qi_y));}}return points;
}

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

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

相关文章

详解如何利用PHP实现RPC

一、什么是RPC 什么是RPC RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种计算机通信协议&#xff0c;用于使一个计算机程序可以调用另一个运行在不同计算机上的程序的过程或函数&#xff0c;并且无需了解底层网络细节。简而言之&#xff0c…

测试PySpark

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名--章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…

数据结构之手撕顺序表(讲解➕源代码)

0.引言 在本章之后&#xff0c;就要求大家对于指针、结构体、动态开辟等相关的知识要熟练的掌握&#xff0c;如果有小伙伴对上面相关的知识还不是很清晰&#xff0c;要先弄明白再过来接着学习哦&#xff01; 那进入正题&#xff0c;在讲解顺序表之前&#xff0c;我们先来介绍…

代码随想录算法训练营第23期day25| 216.组合总和III 、17.电话号码的字母组合

目录 一、&#xff08;leetcode 216&#xff09;组合总和III 剪枝 二、&#xff08;leetcode 17&#xff09;电话号码的字母组合 思路 一、&#xff08;leetcode 216&#xff09;组合总和III 力扣题目链接 状态&#xff1a;已AC&#xff0c;就是在77题的前提下&#xff0c…

Unity3D 程序员常用的核心类及方法详解

Unity3D是一款强大的游戏引擎&#xff0c;广泛应用于游戏开发领域。作为Unity3D程序员&#xff0c;掌握常用的核心类及方法是非常重要的。本文将详细介绍Unity3D中程序员常用的核心类及方法&#xff0c;并给出代码实现。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff…

基于ssm的旅游管理系统

功能如下图所示 摘要 基于SSM框架的旅游管理系统代表了信息技术在旅行业中的崭新机遇&#xff0c;为旅行企业提供了强大的工具&#xff0c;以应对现代旅游市场的复杂挑战。这个系统的研发和实施具有广泛的研究意义&#xff0c;它深刻影响了旅游业的发展&#xff0c;具体表现如下…

简单测试一下 展锐的 UDX710 性能

最近在接触 联通5G CPE VN007 &#xff0c;发现使用的是 展锐的Unisoc UDX710 CPU&#xff0c;正好简单的测试一下这颗CPU CPU信息 UDX710 是一颗 双核 ARM Cortex-A55 处理器&#xff0c;主频高达 1.35GHz processor : 0 BogoMIPS : 52.00 Features : fp…

QT最小化到托盘显示

一、效果&#xff1a; 程序关闭后&#xff0c;程序并没有退出&#xff0c;而是放入了托盘中&#xff1b;点击恢复原始大小&#xff0c;或者双击托盘图标&#xff0c;可以恢复程序原来的窗口。如下图。 那qt是如何实现这样的办法呢&#xff0c;其实就是用到了 QSystemTrayIcon类…

2023.10.17 关于 wait 和 notify 的使用

目录 引言 方法的使用 引入实例&#xff08;wait 不带参数版本&#xff09; wait 方法执行流程 wait 和 notify 组合实例 wait 带参数版本 notify 和 notifyAll 的区别 经典例题 总结 引言 线程最大的问题是抢占式执行&#xff0c;随机调度虽然线程在内核里的调度是随…

SpringBoot_redis使用实战(四)_消息模式

redis消息 1.简介2.入门2.1 编写消息监听器2.2 注册消息监听器2.3 发送消息 3.进阶3.1ChannelTopic和PatternTopic3.1.1. ChannelTopic3.1.2. PatternTopic 3.2 可靠性 4.总结 1.简介 MessageListener是Spring Data Redis中的一个接口&#xff0c;它定义了处理接收到的Redis消…

c++ 高效使用vector(面试)

文章目录 1.善用Reserve提前分配足够的空间2. 使用 shrink_to_fit() 释放 vector 占用的内存&#xff0c; – clear() 或 erase() 不会释放内存3 在填充或者拷贝到 vector 的时候&#xff0c;应该使用赋值而不是 insert() 或push_back()4 遍历 std::vector 元素的时候&#xff…

Maven多模块管理(转载)

注意&#xff1a;父模块需设定打包方式为pom https://cloud.tencent.com/developer/article/1667275 dependencyManagement 统一管理子类依赖版本 在父类maven中加入&#xff0c;不会继承给子类&#xff0c;只能规定子类的依赖版本&#xff0c;子类加入dependence后无需写入 …

【前端学习】—JS判断数据类型的方式有哪些(八)

【前端学习】—JS判断数据类型的方式有哪些&#xff08;八&#xff09; 一、JS中判断数据类型的场景 二、JS中有哪些数据类型 三、JS判断数据类型的方式有哪些 const arr[]; const object{};const number1; const stringstring;//typeofconst typetypeof arr; console.log(type…

从头开始机器学习:神经网络

一、说明 如果你还没有做过逻辑回归&#xff0c;你会在这里挣扎。我强烈建议在开始之前查看它。您在逻辑回归方面的能力将影响您学习神经网络的难易程度和速度。 二、神经网络简介 神经网络是一个神经元网络。这些神经元是逻辑回归函数&#xff0c;它们被链接在一起形成一个网络…

只会Python,怎么用PC控制无人机自动飞行?

PC-SDK是阿木实验室 (AMOVLAB) 为了简化开源飞控的控制协议MAVLink&#xff0c;优化和维护的一个基于PC电脑运行MAVSDK(支持Windows和Ubuntu)的Python SDK库。 相对于传统的无人机控制开发&#xff0c;开发者无需掌握C/C语言和ROS等相关知识&#xff0c;只要学会Python编程及懂…

Gin:获取本机IP,获取访问IP

获取本机IP func GetLocalIP() []string {var ipStr []stringnetInterfaces, err : net.Interfaces()if err ! nil {fmt.Println("net.Interfaces error:", err.Error())return ipStr}for i : 0; i < len(netInterfaces); i {if (netInterfaces[i].Flags & ne…

leetcode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和

1143. 最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些…

wsl使用vscode连接,远程安装C/C++ 拓展时,报错

报错内容&#xff1a; EACCES: permission denied, rename /home/wen/.vscode-server/extensions/.b61b1c7c-f703-4dfd-bdc5-d9a00681c4b7 -> /home/wen/.vscode-server/extensions/ms-vscode.cpptools-1.17.5-linux-x64 解决办法&#xff1a; 升级wsl到wsl2就好了。 &a…

Vue-router快速入门 是什么 如何跳转 如何传值的问题

3.1 Vue-router是什么 Vue-router:Vue.js 的官方路由为 Vue.js 提供富有表现力、可配置的、方便的路由 官网&#xff1a;https://router.vuejs.org/zh/ 作用&#xff1a; 1.实现vue页面(组件)的跳转 2.可以在跳转的时候携带参数 3.2 Vue3使用Vue-router(静态路由) 基于Vu…

C# CodeFormer Inpainting 人脸填充

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace CodeFormer_D…