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

QT:计算点到线段的垂线段的距离

描述 

在Qt中,要计算一个点到一条线段的垂线段的长度(即点到线段上最近点的距离,且这个点是垂直于线段的),你不能直接使用QVector2D::distanceToLine,因为这个方法计算的是点到直线的垂直距离,而不是到线段的垂直距离。线段有起点和终点,而直线是无限延伸的。

为了计算点到线段的垂线段长度,你需要考虑几种情况:

  1. 如果点的投影在线段上,则垂线段长度就是点到投影点的距离。
  2. 如果点的投影在线段的起点或终点之外,则垂线段长度是点到线段起点或终点的距离中的较小值(这个没搞清楚。好在我当前的需求,不会出现投影在线段之外的情况)。

下面是一个使用QVector2D和简单的几何计算来实现这一功能的示例代码:

实验代码 

函数:

qreal Widget::pointToSegmentDistance(const QVector2D &point, const QVector2D &segmentStart, const QVector2D &segmentEnd) {QVector2D segmentDirection = segmentEnd - segmentStart;QVector2D vecFromStartToPoint = point - segmentStart;// 计算投影系数qreal t = QVector2D::dotProduct(vecFromStartToPoint, segmentDirection) / QVector2D::dotProduct(segmentDirection, segmentDirection);qDebug() << t;// 如果投影系数小于0,则最近点是线段起点if (t < 0.0) {return QVector2D(point - segmentStart).length();}// 如果投影系数大于1,则最近点是线段终点if (t > 1.0) {return QVector2D(point - segmentEnd).length();}// 投影在线段上,计算垂线段长度QVector2D projection = segmentStart + t * segmentDirection;return QVector2D(point - projection).length();
}

在paintEvent函数中实现划线,并调用 pointToSegmentDistance计算垂线段距离

void Widget::paintEvent(QPaintEvent *event)
{qreal distance;QPainter painter(this);QPen pen(Qt::blue,3);painter.setPen(pen);QPointF point(100,100);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawPoint(point);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(QPointF(100,100),"point");QVector2D point_2d(point);QLineF line(50,50,50,150);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawLine(line);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(line.center(),"line_1");QVector2D line_start_2d(line.p1());QVector2D line_end_2d(line.p2());distance = pointToSegmentDistance(point_2d,line_start_2d,line_end_2d);qDebug() << " to line 1 distance : " << distance;QLineF line2(50,50,150,50);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawLine(line2);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(line2.center(),"line_2");QVector2D line2_start_2d(line2.p1());QVector2D line2_end_2d(line2.p2());distance = pointToSegmentDistance(point_2d,line2_start_2d,line2_end_2d);qDebug() << " to line 2 distance : " << distance;QLineF line3(150,50,150,150);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawLine(line3);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(line3.center(),"line_3");QVector2D line3_start_2d(line3.p1());QVector2D line3_end_2d(line3.p2());distance = pointToSegmentDistance(point_2d,line3_start_2d,line3_end_2d);qDebug() << " to line 3 distance : " << distance;QLineF line4(150,200,150,300);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawLine(line4);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(line4.center(),"line_4");QVector2D line4_start_2d(line4.p1());QVector2D line4_end_2d(line4.p2());distance = pointToSegmentDistance(point_2d,line4_start_2d,line4_end_2d);qDebug() << " to line 4 distance : " << distance;QLineF line5(300,200,300,150);pen.setColor(Qt::blue);painter.setPen(pen);painter.drawLine(line5);pen.setColor(Qt::red);painter.setPen(pen);painter.drawText(line5.center(),"line_5");QVector2D line5_start_2d(line5.p1());QVector2D line5_end_2d(line5.p2());distance = pointToSegmentDistance(point_2d,line5_start_2d,line5_end_2d);qDebug() << " to line 5 distance : " << distance;
}

测试结果:

qDebug输出的结果:

小结 

相关文章:

QT:计算点到线段的垂线段的距离

描述 在Qt中&#xff0c;要计算一个点到一条线段的垂线段的长度&#xff08;即点到线段上最近点的距离&#xff0c;且这个点是垂直于线段的&#xff09;&#xff0c;你不能直接使用QVector2D::distanceToLine&#xff0c;因为这个方法计算的是点到直线的垂直距离&#xff0c;而…...

经典5级流水线概述

抽象化的流水线结构&#xff1a; 流水线的基本概念 多个任务重叠&#xff08;并发/并行&#xff09;执行&#xff0c;但使用不同的资源流水线技术提高整个系统的吞吐率&#xff0c;不能缩短单个任务的执行时间其潜在的加速比&#xff1d;流水线的级数 流水线正常工作的基本条件…...

LSTM模型实现电力数据预测

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色&a…...

jmeter学习(7)beanshell

beanshell preprocessor 发送请求前执行 beanshell postprocessor 发送请求前执行 获取请求相关信息 String body sampler.getArguments().getArgument(0).getValue(); String url sampler.getPath(); 获取响应报文 String responseprev.getResponseDataAsString(); 获…...

TCP_SOCKET编程实现

文章目录 与UDP_SOCKET的区别第一代Tcp_ServerTcp_Client第二代Tcp_Server第三代Tcp_server多线程版本Tcp_Server线程池版的Tcp_Server使用inet_ntop来解决线程安全问题 业务逻辑编写总结补充说明&&业务代码完成ping的真实作用Translate编写Transform业务代码 整体总结…...

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习07(基于docker容器的防火墙及NAT企业实战)

7.1 网络准备 7.2 网络规划 1&#xff09;虚拟网络编辑器 点击右下方“更改设置”&#xff0c;点击“添加网络”假如vmnet3和vmnet4&#xff0c;然后分别选择vmnet3和vmnet4&#xff0c;设置为“仅主机模式”&#xff0c;按③处处理&#xff0c;去掉“使用DHCP”&#xff0c;…...

②EtherNet/IP转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherNet/IP 转 Modbus TCP &#xff08;接上一章&#xff09; GW系列型号 配置使用 与 EtherNet/IP 主站进行组态说明 这里介…...

Java 集合(Collection)

1.什么是集合&#xff1f; 对象的容器&#xff0c;定义了对多个对象进行操作的常用方法&#xff0c;属于接口类型。 2.集合和数组的区别 &#xff08;1&#xff09;数组长度固定&#xff0c;集合长度不固定 &#xff08;2&#xff09;数组可以存储基本类型和引用类型&#…...

Windows系统编程(三)线程并发

进程与线程 进程&#xff1a;直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说&#xff0c;进程仅仅是一个数据结构&#xff0c;并不会真实的执行代码 线程&#xff1a;通常被称作但并不真的是轻量级进程或实际工作中的进程&#xff0c;它会真实的执行代码。每…...

【Qt】控件概述(2)—— 按钮类控件

控件概述&#xff08;2&#xff09; 1. PushButton2. RadioButton——单选按钮2.1 使用2.2 区分信号 clicked&#xff0c;clicked(bool)&#xff0c;pressed&#xff0c;released&#xff0c;toggled(bool)2.3 QButtonGroup分组 3. CheckBox——复选按钮 1. PushButton QPushB…...

Java访问器方法和更改器方法

一.访问器方法 1.访问器方法的定义和用途 访问器方法&#xff0c;通常也称为getter方法&#xff0c;是一种在面向对象编程中用于从类的外部访问私有字段值的特殊方法。这些方法的设计目的是为了提供对类内部状态的受限访问&#xff0c;同时保持类的封装性。通过使用访问器方法&…...

CAN协议帧结构

一、数据帧的整体结构 ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐ │ SOF │ ID[11]│ RTR │ IDE │ DLC │ Data …...

valgrind 单例模式的自动释放(多线程)

单例模式&#xff0c;其中对象是由_pInstance指针来保存的&#xff0c;而在使用单例设计模式的过程中&#xff0c;也难免会遇到内存泄漏的问题。那么是否有一个方法&#xff0c;可以让对象自动释放&#xff0c;而不需要程序员自己手动去释放呢&#xff1f; ——嵌套类 5.1、内…...

OpenFegin

文章目录 一、OpenFegin是什么&#xff1f;二、基本使用三、超时重试机制4.自定义超时重传机制五、底层实现 一、OpenFegin是什么&#xff1f; OpenFeign的全称为Spring Cloud OpenFeign(下文简称OpenFeign),是Spring Cloud团队开发的一款基于 Feign的框架&#xff0c;声明式W…...

LeetCode-2608. 图中的最短环【广度优先搜索 图,腾讯面试真题】

LeetCode-2608. 图中的最短环【广度优先搜索 图&#xff0c;腾讯面试真题】 题目描述&#xff1a;解题思路一&#xff1a;【一图秒懂】枚举起点跑 BFS解题思路二&#xff1a;背诵版解题思路三&#xff1a; 题目描述&#xff1a; 现有一个含 n 个顶点的 双向 图&#xff0c;每个…...

IDEA 编译报错 “java: 常量字符串过长” 的解决办法

目录 一、问题描述二、问题原因2.1 理论角度2.2 源码角度 三、解决方案解决方案①&#xff1a;StringBuilder 拼接解决方案②&#xff1a;读取文件内容 四、方案验证 在线文本换行工具&#xff1a; https://lzltool.cn/Toolkit/WrapWordsInText 一、问题描述 今天在开发过程中…...

RK3568平台开发系列讲解(I2C篇)I2C 总线实现 client 设备方法

🚀返回专栏总目录 文章目录 一、非设备树实现 i2c client1.1、i2c_new_device1.2、i2c client二、设备树实现 i2c2.1、i2c_client 结构体的生成2.2、i2c_driver 驱动2.2.1、module_i2c_driver2.2.2、fan53555_regulator_probe沉淀、分享、成长,让自己和他人都能有所收获!�…...

K8S安装和部署

环境部署说明 主机IPmaster172.25.254.100node10172.25.254.10node20172.25.254.20harbor172.25.254.233 所有节点禁用selinux和防火墙 所有节点同步时间和解析 所有节点安装docker-ce 所有节点禁用swap&#xff0c;注意注释掉/etc/fstab文件中的定义 解析配置&#xff08;…...

Singleton(单例模式)

1. 意图 在开发中&#xff0c;若某些模块或功能只需要一个类实例&#xff0c;所有调用地方通过着一个类对象访问功能&#xff0c;单例模式符合这种类实例创建模式&#xff0c;并且通过提供统一类实例接口访问类对象。 2. 适用性 《Gof 设计模式-可复用面向对象软件的基础》中对…...

【Linux报错】“-bash: cd: too many arguments“

问题描述 今天使用 cd 想要调整某个文件目录时&#xff0c;发现以下报错 原因分析&#xff1a; arguments 是参数的意思&#xff0c;该报错提示参数过多&#xff0c;意味着系统识别到了多余参数 本质原因&#xff1a;你的命令中输入了多余的 ”空格“ &#xff0c;检查一…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...