清华计算几何-线段求交与BO算法

2024-08-26 06:36

本文主要是介绍清华计算几何-线段求交与BO算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

单轴线段求交

给定单边轴下,  N定线段,检查出相交的线段.

解法一: 暴力求解

遍历所有线段对,进行相交判断, 算法复杂度为O(n2)

解法二: LR扫描

把每条线段的头尾认定为L和R。对所有点进行排序,如果每两个点满足LL或者RR,则对应的线段相交。如果为LR,则对应的线段无相交,算法复杂度为O(nlog(n))

多轴线段求交 - BO算法(line sweep)

上面强调是单个坐标轴的线段求交,扩展到XY轴甚至更多轴.

比较常用的算法有 bentley–ottmann algorithm, 简称BO算法。

利用扫描线进行求交的算法.

算法复杂度: O((n + I) * logn)

空间: O(n + I)

N为线段总数, I为线段交点.

扫描线相交线的垂直排序(从上到下)

扫描线为垂直线, 自左向右扫描,  在x = t时刻, 扫描线与多条线段相交, 按照相交点的高度从上往下排序, 在最上面交点所在的线段顺序最高,然后依次往下降低。

事件点和扫描线移动导致垂直排序变化(从左到右)

随着扫描线的移动,假设原来线段A的顺序高于线段B,但是经过某些关键点变化,他们的相对顺序会颠倒。这些点成为事件(Event)

扫描线移动的时候导致垂直排序发生改变的三个关键时间点:

[1]线段左端点

[2]两条线段相交点

[3]线段右端点

BO算法使用的数据结构

前面说到BO算法由扫描线从左向右扫描, 扫描线时刻会和某部分线段产生相交事件(左右端点 + 相交事件), 而多条线段之间又存在高度之间的顺序排列以及顺序变化。

EventQueue

从左到右经过线段的左右端点和相交点都为事件点。

优先队列

Status Struct

和扫描线X = t正在相交的线段,进行上下维度的高度排序

平衡二叉树

扫描线从左到右扫描线段的三种情况

扫描线进行扫描的EventQueue案例

扫描线相交线段上下维度的StatusStruct变化的案例

(线段左端点,右端点,和相交事件)三种事件下StatusStruct都会产生变化,BBST(平衡二叉树)实现其中的删减和重新排序

BO算法中判断线段相交是前面线段三类事件决定的结果--案例

其中f和e相交就是线段P右端点引发的事件后果.(三类事件中的第二类事件)

BO算法特殊情况下效率低下--重复测试

参考资料

[1]清华计算几何 P66 - P82

这篇关于清华计算几何-线段求交与BO算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107819

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.