线段交点检测:扫描线算法

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 

几何对象的相交检测是计算几何中的一项基本操作。它具有广泛的应用,其中一些列在下面:

  • 计算机游戏和模拟中的碰撞检测。
  • 计算机图形学中的射线射击。
  • 地理信息系统 (GIS) 中的地图叠加。
  • 机器人导航中的防撞。
问题陈述:给定平面中 𝑛 条线段的集合 𝑆 = { 𝑠1, 𝑠2, …, 𝑠𝑛},报告所有交点:

七条线段求交问题实例

1、朴素算法:检查所有线段对

𝑛 线段的交点数范围从零(没有一对线相交)到 𝑂(𝑛^2)(所有对相交)。

简单的朴素方法检查所有线段对之间的交点。由于所有线段对都可能相交,因此朴素算法对于最坏情况的输入是最佳的,时间复杂度为 𝑂(𝑛^2)。

对于输出大小变化的问题,输出敏感算法是首选,因为它们的时间复杂度取决于问题大小和输出大小。对于具有 𝑛 线段的线段相交问题的实例,让 𝑘 表示交点数。

现在我们将讨论用于线段相交检测的 𝑂((𝑛+𝑘)𝑙𝑜𝑔(𝑛)) 扫描线算法。对于二维平面中的各种几何问题,扫描线算法是一种基本且有效的方法。这些算法涉及系统地扫描平面上的垂直线或水平线,以处理和分析几何对象,例如线段、点或其他几何实体。

2、一般位置假设

在解决几何问题时,可以方便地忽略几何输入的某些特殊配置,以保持算法简单。这些特殊情况是单独处理的。当它们被忽略时,问题的输入被视为处于一般位置,一般位置假设定义了重合配置。

对于线段相交问题,忽略以下特殊配置:

  • 没有三条线在同一点相交。
  • 没有端点位于另一个线段上。
  • 端点和交点的𝑥坐标是唯一的。

一般位置假设忽略的配置

3、扫描线算法

垂直扫描线从左到右扫描输入。扫描线与线段的交点用于发现即将发生的交点。

3.1 扫描线状态和事件点

设 𝑙 表示垂直扫描线。与扫描线 𝑙 相交的线段按从上到下的顺序存储。这称为扫描线状态。

扫描线 l 与四条线段相交

我们注意到,只有当扫描线遇到输入中的某些特殊点时,扫描线状态才会发生变化。这些点称为事件点,下面列出了它们以及它们在扫描线状态中触发的变化。

  • 线段𝑠的左端点:在正确的位置添加线段𝑠。
  • 线段𝑠的右端点:删除线段𝑠。
  • 一对线段𝑠和𝑟的交点:交换𝑠和𝑟的顺序。

由于扫描线状态仅在事件点处发生变化,因此扫描线可以从一个事件点跳转到下一个事件点,而不是连续扫描平面。

为了保证𝑂((𝑛+𝑘)𝑙𝑜𝑔(𝑛))的时间复杂度,扫描线状态和事件点存储在支持𝑂(𝑙𝑜𝑔𝑛)操作的数据结构中。

3.2 数据结构

扫描线状态是与扫描线相交的线段的从上到下的有序列表,存储在有序字典中。事件点存储在优先级队列中。这些数据结构中的每一个都支持以下操作。

扫描线状态的有序字典

𝑂(𝑙𝑜𝑔 𝑛) 中的有序字典支持以下操作:

  • 插入线段
  • 删除线段
  • 获取前任
  • 获取后继
  • 交换两个线段
事件点的优先级队列

𝑂(𝑙𝑜𝑔 𝑛) 中的事件队列支持以下操作:

  • 插入事件点
  • 删除事件点
  • 提取优先级最高的事件点

3.3 算法与案例分析

扫描线算法以一个空的事件队列和一个空的有序字典开始。开始时,所有线段的端点都插入到事件队列中。在事件队列中,具有最低𝑥坐标的点具有最高优先级,表示扫描线从左向右移动。在算法过程中,交点会动态添加到事件队列中并从中删除。

请注意,任何两个相交的线段在相交之前在扫描线上相邻。因此,该算法仅将相邻线段之间的交点插入事件队列,将不相邻线段之间的交点的发现推迟到后期。

当新的线段插入优先级队列时,算法会检查其与前一个和后一个线段的交点,而不是检查其与扫描线上所有 𝑂(𝑛) 个线段的交点。这确保了处理每个事件点所花费的时间是 𝑂(𝑙𝑜𝑔 𝑛)。

接下来,我们来看看三种事件点的扫描线状态和事件队列是如何变化的。在接下来的三幅图中,虚线灰色线是扫描线。

线段𝑠的左端点

发现左端点标志着发现了一条新的线段,从而触发了扫描线状态和事件点的以下变化:

  • 在扫描线上插入𝑠。让𝑞和𝑡成为扫描线上𝑠上方和下方的线段。
  • 从事件队列中删除𝑞和𝑡之间的交点(如果适用),如下图所示为红色圆圈,因为它们不再相邻。
  • 检查𝑞,𝑠和𝑠,𝑡对之间的交点,如果线段相交,则将它们添加到事件队列中。

扫描线 l 发现线段 s 的左端点

线段 𝑠 的右端点

右端点的发现会触发扫描线状态和事件点的以下变化:

  • 让 𝑞 和 𝑡 成为扫描线上 𝑠 上方和下方的线段。
  • 从扫描线状态中移除 𝑠。
  • 检查 𝑞 和 𝑡 之间的交点,如果交点存在于扫描线的右侧,则将其添加到事件队列中。

请注意,𝑞、𝑠 或 𝑠、𝑡 对之间的可能交点位于过去,并且已被算法发现。

扫描线 l 发现线段 s 的右端点

线段𝑠和𝑟的交点

发现交点后,将其添加到解决方案中,并对扫描线状态和事件点进行以下更改:

  • 让𝑞成为𝑟的前任,𝑡成为𝑠在扫描线上的后继。
  • 交换扫描线上的线段𝑟和𝑠。
  • 从事件队列中删除对𝑞,𝑟和𝑠,𝑡(如果适用)之间的交点,如下图红色圆圈所示,因为这些对不再相邻。
  • 检查对𝑞,𝑠和𝑟,𝑡之间的交点,如果它们存在于扫描线的右侧,则将它们添加到事件队列中。

扫描线 l 发现线段 s 和 r 的交点

概括来说,检查扫描线上任何一对相邻的线段的交点,并将交点添加到事件队列中。任何一对不再相邻的线段的交点将从事件队列中删除。

4、复杂度分析

对于具有𝑛线段和𝑘交点的输入,算法需要处理的事件有2𝑛+𝑘=𝑂(𝑛+𝑘)个。每个事件需要𝑂(𝑙𝑜𝑔 𝑛)时间来更新数据结构。因此,扫描线算法的时间复杂度为𝑂((𝑛+𝑘)𝑙𝑜𝑔 𝑛) 。


原文链接:线段交点检测扫描线算法 - BimAnt

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

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

相关文章

ChatGPT Edu版本来啦:支持GPT-4o、自定义GPT、数据分析等

5月31日,OpenAI在官网宣布,推出ChatGPT Edu版本。 据悉,这是一个专门为大学校园提供的ChatGTP,支持GPT-4o、网络搜索、自定义GPT、数据分析、代码生成等功能,可以极大提升学生、老师的学习质量和教学效率。 目前&…

【UE5教程】使用蓝图显示鼠标

首先,在您的项目中创建一个新的蓝图类,继承自PlayerController。在蓝图编辑器中,找到Event BeginPlay节点,并从它引出一条线。添加Set Show Mouse Cursor节点,勾选Visible,以确保鼠标在游戏开始时可见。 鼠…

python-web应用程序-Django数据库

python-web应用程序-Django数据库-操作表 原始方法: import pymysql#1.链接mysql conn pymysql.connect(host127.0.0.1,port 2206,user root,passwd root123,charset utf8,db unicom) cursor conn.cursor(cursor pymysql.cursors.DictCursor)#2.发送指令 …

1.4 Unicode简介

现在的Windows操作系统有许多不同语言版本,可以支持所有国家现有的语言文字。这就涉及到不同字符集的编码规则。 本节必须掌握的知识点: 字符集 C语言款字符 宽字符和Windows 1.4.1 字符集 ■ANSI多字节字符集 ●ASCII码 现代计算机发源于美国&…

云原生架构案例分析_3.某快递公司核心业务系统云原生改造

名称解释: 阿里云ACK:阿里云容器服务 Kubernetes 版 ACK(Container Service for Kubernetes)集成Kubernetes网络、阿里云VPC、阿里云SLB,提供稳定高性能的容器网络。本文介绍ACK集群网络及阿里云网络底层基础设施的重要…

[Algorithm][动态规划][回文串问题][回文子串][最长回文子串][分割回文串Ⅳ]详细讲解

目录 0.原理讲解1.回文子串1.题目链接2.算法原理详解3.代码实现 2.最长回文子串1.题目链接3.代码实现 3.分割回文串 IV1.题目链接2.算法原理详解3.代码实现 0.原理讲解 动态规划能够将所有的子串是否是回文的信息,保存在dp表里面状态表示一般经验:以[i,…

Harmony开发 List/Scroll 组件最后一个item显示不全或布局显示不完整

今天在做Harmony开发的时候遇到一个问题,List组件的最后一个item显示不全,如下图,item-9显示不出来,显示了一部分 这个页面的代码结构如下: Column() {Row() {Text(文本1).fontSize(15).fontColor(Color.Black)Text(文本2).font…

基于Vue3的Uniapp实训项目|一家鲜花店

基于Vue的Uniapp实训指导项目 项目预览: 在这里插入图片描述 pages.json {"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages{"path": "pages/index/index",&…

群体优化算法---蜂群优化算法应用于数据挖掘

介绍 蜂群优化算法(Bee Algorithm, BA)及其变种主要模拟蜜蜂的觅食行为,以解决复杂的优化问题。这类算法通过蜜蜂之间的信息交流和协作来探索解空间,寻找全局最优解。主要应用于参数优化,结构优化,机器学习…

The First项目报告:去中心化知识产权治理协议MON Protocol如何革新链游产业?

2023年12月,RPG NFT 游戏 Pixelmon 首席执行官 GiulioX 在 X 平台表示,确认将推出代币 MON,代币生成(TGE)时间将取决于 MON 的路线图和主流 CEX 的启动板队列。12 月 11 日,RPG NFT 游戏 Pixelmon 首席执行…

element-plus的Layout组件

elment-plus的layout组件包括el-row和e-col,和bootstrap的栅格类似,e-row采用flex布局,分成了24个栅栏,单个e-col默认占24,可以通过span属性指定其大小,offset属性指定其偏移的栅栏个数。e-row组件的父组件不要使用dis…

深度学习(三)

5.Functional API 搭建神经网络模型 5.1利用Functional API编写宽深神经网络模型进行手写数字识别 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom…

Stable diffusion文生图大模型——隐扩散模型原理解析

1、前言 本篇文章,我们将讲这些年非常流行的文生图大模型——Stable Diffusion。该模型也不难,甚至说很简单。创新点也相对较少,如果你学会了我以前的文章讲过的模型,学习这个也自然水到渠成! 参考论文:H…

腾讯云 TDMQ for Apache Pulsar 多地区高可用容灾实践

作者介绍 林宇强 腾讯云高级工程师 专注于消息队列、API网关、微服务、数据同步等 PaaS 领域。有多年的开发和维护经验,目前在腾讯云从事 TDMQ Pulsar 商业化产品方向的研发工作。 导语 本文将从四个维度,深入剖析 Pulsar 在多可用区高可用领域的容…

大数据—元数据管理

在大数据环境中,元数据管理是确保数据资产有效利用和治理的关键组成部分。元数据是描述数据的数据,它提供了关于数据集的上下文信息,包括数据的来源、格式、结构、关系、质量、处理历史和使用方式等。有效的元数据管理有助于提高数据的可发现…

Amazon云计算AWS(四)

目录 八、其他Amazon云计算服务(一)快速应用部署Elastic Beanstalk和服务模板CloudFormation(二)DNS服务Router 53(三)虚拟私有云VPC(四)简单通知服务和简单邮件服务(五&…

LeetCode刷题之HOT100之全排列

九点半了&#xff0c;做题吧。聊天聊到十一点多哈哈。 1、题目描述 2、逻辑分析 给定一个不重复数组&#xff0c;要求返回所有可能的全排列。这道题跟我上一道题思想一致&#xff0c;都是使用到回溯的算法思想来解决。直接用代码来解释吧 3、代码演示 public List<List&…

MongoDB环境搭建

一.下载安装包 Download MongoDB Community Server | MongoDB 二、双击下载完成后的安装包开始安装&#xff0c;除了以下两个部分需要注意操作&#xff0c;其他直接next就行 三.可视化界面安装 下载MongoDB-compass&#xff0c;地址如下 MongoDB Compass Download (GUI) | M…

Golang | Leetcode Golang题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; type pair struct {node *TreeNodenum int }func sumNumbers(root *TreeNode) (sum int) {if root nil {return}queue : []pair{{root, root.Val}}for len(queue) > 0 {p : queue[0]queue queue[1:]left, right, num : p.node.Left, …

Spire.PDF for .NET【文档操作】演示:在 C# 中向 PDF 文件添加图层

Spire.PDF 完美支持将多页 PDF 拆分为单页。但是&#xff0c;更常见的情况是&#xff0c;您可能希望提取选定的页面范围并保存为新的 PDF 文档。在本文中&#xff0c;您将学习如何通过 Spire.PDF 在 C#、VB.NET 中根据页面范围拆分 PDF 文件。 Spire.PDF for .NET 是一款独立 …