图形基础算法:如何将点与带曲线边的多边形位置关系算法做稳定

简介

判断点与多边形位置关系算法是几何算法中最基础的算法之一,包括布尔运算在内的非常非常多的算法都会用到它。它的稳定是算法库稳定的关键。

下面我们从一个边都是直线的多边形开始了解射线法的原理。然后看看引入曲线后会带来哪些问题,以及在实际应用还有哪些其他问题。最后看看如何实现一个稳定的,支持曲线边多边形的点与多边形位置关系算法。

射线法

讲射线法的资料很多,用AI也能轻松查到详细内容,所以我们只简单介绍一下重点,为后面内容做个铺垫。

射线法的实现思路是以被检测点为起点做一条射线,看和多边形有几个交点,奇数个交点说明在内部,偶数个交点说明在外部(0算偶数)。

实际中往往以x轴正方向做射线,这样计算比较简单。

交点计数时,要考虑各种相交类型,例如射线和边重合,射线过顶点等。

有一个已经总结好的的原则可以直接使用(以x轴正方向射线为例):

当边的一个顶点的y大于参考点的y,另一个顶点的y不大于参考点的y(等于或小于),且边与x轴交点的x大于参考点的x时计数加一。

如何判断点是否在多边形上呢?因为一般这个判断都需要带一个精度,所以直接用上面介绍方法中的得到的边与x轴交点到参考点x的距离是不准确的。

我见过两种方式:

一种是单独判断点是否在边上。

另一种是点加上精度会得到一个Box,用这个Box的顶点分别做射线法,如果有些顶点为内部,有些顶点为外部则认为是点在多边形上边。

两种方法适用的是不同的场景,大家按需选择。

曲线边给基础射线法稳定性带来的挑战

首先曲线与射线相交可能会有多个交点,我们就不能只拿曲线的两个端点来判断了,而是要根据交点位置曲线是否穿过射线来判断是否计数加一。

是否穿过一般用交点处的切线方向来判断。但如果曲线和切线相切时,就需要根据二阶导数甚至更高阶导数来判断穿过关系了。

但相切本身就是个带精度判断的问题。一阶导数小于多少用二阶导数,二阶导数小于多少用三阶导数。这个没有唯一的结论。一个场景对了,另一个场景可能就不对了

另外,相切时,因为精度的问题,我们几乎不可能计算到恰巧相切的点。不是偏左点就是偏右点,甚至参数域上偏很多都有可能。如果曲线曲率很大,这个偏差也可能对切线方向带来比较大的影响,从而影响稳定性。

还有就是,边都是直线时,我们可以保证各边之间无缝连接。是曲线时就很难保证无缝连接了。原因是因为曲线的表示方式导致的。

例如画图时我们用三点定义圆弧,但圆弧在内存中存储时用圆心半径和角度。那么我们根据三点计算出的圆心半径和角度再反算回三点时,在特殊场景中是存在误差的。这个误差就会导致边连接处存在一个小小的缝隙,这个小小的缝隙出现在射线附近时就有可能导致错误。

有些算法库,多边形是其他运算的结果(例如布尔运算),本身可能就带符合误差要求的缝隙(因为有可能基于效率原因考虑不做缝隙修复)。

上面提到的情况绝对不是危言耸听,都是我们在实际项目中碰到过的。算法本身不难,难的是如何在各种场景下都能表现的稳定。

为了给大家对上面说的有个更直观的认识,我画了个草图放到下面。

在这里插入图片描述

稳定的射线法

基于前面的讨论,相切或接近相切时,从理论上就是不能解决的。

一个最简单的解决思路是,检测上述情况,发现出现了就再换一条射线。

从概率上,这种算法没问题。但多边形复杂时,有可能需要换好几次射线才能得出结果。另外,如果射线不是x轴或y轴方向时,直线和曲线求交的效率也会下降。

下面介绍一下我们设计的算法思路。

1. y轴正方向做射线,计算所有交点。

2. 根据交点统计计数和可信度,可信度符合要求则直接返回结果。

3. 如果多边形有顺逆时针方向,根据第一个交点的穿过形式和可信度判断内外,可信度满足要求直接返回结果。

4. y轴负方向做射线,计算所有交点。

5. 根据交点统计计数和可信度,可信度符合要求则直接返回结果。

6. 如果多边形有顺逆时针方向,根据第一个交点的穿过形式和可信度判断内外,可信度满足要求直接返回结果。

7. 利用交点把多边形打断成片段,这些片段是被y轴正负方向射线分开的。

8. 判断片段的两个端点是否在x轴方向射线同侧,如果在同侧不影响计数,直接不用考虑。

9. 如果不在同侧,统计在y轴正方向射线的右侧片段数,这个片段数就是判断内外的计数。这步可以通过采用的方式判断是否在右侧。

如下图所示:

在这里插入图片描述

总结

这可能就是书本中的算法和在大厂中实际跑的算法的区别。书本中的算法追求理论可行,实际应用的算法追求实践可行。

虽然我以前写过好多版这个算法了,但为了写这篇文章,我又把它实现了一遍,源码放到星球里了。为了省时间目前只做了直线求交,但算法本身是支持曲线的。

星球中的Demo可直接调试运行,学源码能看到很多细节,欢迎加入我们的星球,支持一下作者。现有源码已经很值得加入了。后续算法源码还会不断在星球中发布。

在这里插入图片描述

星球地址:https://t.zsxq.com/bVB9h

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

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

相关文章

react的filber架构

好问题 👍 你问的是 React Fiber 架构。这是 React 16 引入的核心机制,用来解决 React 在大规模更新时的性能问题。下面我给你从 背景 → Fiber 是什么 → 原理 → 优点 → 流程 来系统讲。一、为什么需要 Fiber?在 React 15 及以前&#xff…

Lucky STUN穿透结合群晖NAS实现docker下transmission监听端口动态更新

参考文章 LCUKY系列教程 一 「LUCKY STUN穿透」使用 cURL 自动修改 Transmission 的监听端口 二 「LUCKY STUN穿透」使用 Webhook 自动修改 qbittorrent 的监听端口 三 LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则 四「LUCKY STUN穿透」…

如何在Ubuntu畅玩鸣潮等游戏

本教程只包括Steam上的游戏。# 更新软件源 sudo apt update # 安装Steam sudo apt install steam首先,在Ubuntu的snap商店安装Steam,启动,登陆,下载游戏。到这里的操作都比较简单,对于没有反作弊的游戏,往往…

机器学习09——聚类(聚类性能度量、K均值聚类、层次聚类)

上一章:机器学习08——集成学习 下一章:机器学习10——降维与度量学习 机器学习实战项目:【从 0 到 1 落地】机器学习实操项目目录:覆盖入门到进阶,大学生就业 / 竞赛必备 文章目录一、聚类任务(无监督学习…

解决 Docker 构建中 Python 依赖冲突的完整指南

问题背景 在基于 registry.cn-shenzhen.aliyuncs.com/all_dev/dev:invoice-base 镜像构建 Docker 容器时,我们遇到了一个常见的 Python 依赖管理问题: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-…

光子计算芯片实战:Lightmatter Passage互连架构性能评测

点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,80G大显存,按量计费,灵活弹性,顶级配置,学生更享专属优惠。 摘要 随着人工智能计算需求呈指数级增长,传统电子计算…

基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索

概述 2018年,TensorFlow Lite团队的Pete Warden曾提出:“机器学习的未来在于微型化”。如今,随着人工智能向高性能视觉强大的视觉语言模型(Vision-language models, VLMs)发展,对高性能计算资源的需求急剧…

华为Ai岗机考20250903完整真题

华为Ai岗机考20250903 华为自26届秋招(2025年起)对AI岗位机考进行了改革,考试题型调整为20道选择题(15道单选(6分)5道不定项选择(12分))2道编程题(150300)。 题目核心围绕人工智能技术(如Transformer架构…

k8s+jenkins+harbor构建Devops平台

一、环境准备1、准备一主一从k8s机器,(设备好可以一主多从也行)2、一台harbor仓库机器(dockerhub访问不了)二、安装nfs服务1、在k8s机器上yum install nfs-utils -y systemctl start nfs systemctl enable nfs2、创建共…

为什么 socket.io 客户端在浏览器能连上,但在 Node.js 中报错 transport close?

网罗开发(小红书、快手、视频号同名)大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方…

人才教育导向下:老年生活照护实训室助力提升学生老年照护服务能力

一、老年生活照护实训室建设背景与意义 (一)适应老龄化社会需求 我国老龄化程度持续加深,老年照护服务人才缺口不断扩大。培养专业照护人才成为当务之急,职业教育需承担重要责任。点击获取实训室建设方案 (二&…

我在嘉顺达蓝海的安全坚守

作为嘉顺达蓝海的资深安全员,每天清晨 6 点,我都会站在物流基地的入口处,看着一队队橙色的嘉顺达蓝海危险品运输车整齐列队。那抹醒目的橙色,不仅是嘉顺达蓝海的标志,更是我和 200 多名同事坚守 12 年的安全承诺。今天…

云原生监控系统 Prometheus大总结 20250909

本章内容如下: Prometheus 介绍 Prometheus 部署和配置 Node Exporter 采集数据 Pushgateway 采集数据 PromQL 查询语言 Grafana 图形化展示 Prometheus 标签管理 Prometheus 告警机制 Prometheus 服务发现 各种Exporter 高级功能 Prometheus 实现容器监控 Promethe…

EPNN:基于嵌入式偏振神经网络的水下成像增强方法(未做完)

Enhancing Underwater Imaging for Robot through Embedded Polarization Neural Network EPNN:基于嵌入式偏振神经网络的水下成像增强方法 1 论文核心概念 本文提出了一种名为嵌入式偏振神经网络(Embedded Polarization Neural Network, EPNN) 的方法,用于显著提升水下…

基于单片机冷藏运输车环境检测/水产品运输环境检测设计

传送门 👉👉👉👉单片机作品题目速选一览表🚀 👉👉👉👉单片机作品题目功能速览🚀 🔥更多文章戳👉小新单片机-CSDN博客&#x1f68…

基于STM32设计的人体健康监护系统(华为云IOT)_280

文章目录 一、前言 1.1 项目介绍 【1】项目开发背景 【2】设计实现的功能 【3】项目硬件模块组成 【4】设计意义 【5】国内外研究现状 【6】摘要 1.2 设计思路 1.3 系统功能总结 1.4 开发工具的选择 【1】设备端开发 【2】上位机开发 1.5 参考文献 1.6 系统框架图 1.7 系统原理…

先买实现烦过

#include <myhead.h> #define ERR_LOG(msg)do{perror(msg);printf("%d %s %s\n",__LINE__,__func__,__FILE__);}while(0) //定义TFTP默认端口号&#xff08;69&#xff09;和数据包大小&#xff08;516字节&#xff09; #define PORT 69 #define N 516 …

ACD智能分配:轮流分配和排序上限分配的设置

在客户服务中&#xff0c;合理的对话分配是提高服务质量的关键。一洽客服系统针对不同业务场景,提供灵活的客服分配策略,帮助企业实现智能化的客户服务管理&#xff0c;今天我们了解一下对话的轮流分配、排序上限分配、排序优先分配的设置一、轮流分配按照客服登录系统的先后顺…

【postMan / apifox 文件上传】

apifox 需要提供相关插件 失败的请求 { “timestamp”: “2025-09-10T14:44:24.91900:00”, “status”: 500, “error”: “Internal Server Error”, “path”: “/student/import” } 错误&#xff1a;Post “http://localhost:8080/student/import”: dial tcp [::1]:8080:…

视频加水印,推荐使用运营大管家-视频批量加水印软件

运营大管家-视频批量加水印软件介绍“运营大管家-视频批量加水印”是一款功能强大的桌面应用程序&#xff0c;旨在帮助用户高效地为多个视频批量添加自定义水印。无论是品牌宣传、版权保护&#xff0c;还是个性化展示&#xff0c;本软件都能提供灵活的文字水印和图片水印选项&a…