凸包的学习之路

news2024/11/26 3:25:31

学习视频选择的是:清华大学邓俊辉教授的《计算几何》课程

关于我为什么学习 凸包(Convex Hull)?

——在学习过程中遇到了凸包问题,凸包在CV领域的基础性,使我觉得深入了解凸包是必要的。此外,我发现了《计算几何》这一宝藏课程,对我目前涉足的领域犹如前进的灯塔。而凸包又正是《计算几何》的第一课。

菜鸡还是很菜,但进步空间大呀。

什么是凸包?(如果面试官问你这一问题,你该如何作答)

二维平面上有一个点集,点集中有若干个点,就好像将一些钉子钉在桌子上,现在手里有一个橡皮筋,用手拿着,将它套在这些钉子的外面。然后,松手,橡皮筋就会套在“最外面”的那些钉子上,会呈现出一个轮廓,这个轮廓构成的形状,就是凸包。

凸的概念,是几何中常见的概念。如何判定“凸”?如果轮廓内任意两点的连线都在轮廓区域内,那么这个形状就是凸的。

下面,要记录的几种【由平面中一组点集,生成凸包】的算法

在此之前,两个概念——极点(相当于“边界点”)、极边(相当于“边界”)

1.算法策略1: In-Triangle Test

原理:非极点一定在某一或某些三角形的内部,而极点不在任一三角形内部。

思路:(1)先将所有点都标记为极点;(2)对于每一个三角形(p,q,r),如果点s位于其内部,则将s标记为非极点。

四层循环:

for(int p=0;p<n;p++)

        for(int q=p+1;q<n;q++)

                for(int r=q+1;r<n;r++)

                        for(int s=0;s<n;s++){

                                if(s==p || s==q || s==r || !S[s].extreme ) continue;

                                if(Intriangle(S[p],S[q],S[r],S[s]) S[s].extreme = false;

                                }

下面的重点是:

InTriange()这个函数的实现,我首先想到的是向量的叉乘(多学一点是一点,总是没错的)。这里给出的是点的坐标,可将其转化为三个ToleftTest。沿三角形CW方向或者CCW方向,三角形内的点对于三条边的ToleftTest都会返回同一个值(同是ture,或者同是flase,视方向而定)。ToleftTest在后续其他凸包算法中也有着广泛的应用。

 

 OK,在学习了算法思想后,有种手痒的感觉,于是乎在Code::Blocks中实现了一下。

实现效果如下:

我使用了opencv将点绘制了一下,其中,红色点为极点,黄色点为非极点。

2.算法策略2:Extreme Edges

第一个算法根据极点的特性(不在点集中任三点构成的三角形中)来识别极点和非极点,下面这个算法策略则从极边入手。非极点与非极点之间肯定不存在极边,极点与非极点之间也肯定不存在极边,此外,极点与极点之间也不一定存在极边。那极边的特性是,除了构成该极边的两个极点之外,剩下所有的点都在该极边的一边。

amazing

思路:(1)定义极边EE为空集;(2)对于点集中任两点(p,q)构成的边,判断其他点是否都在该边的同一侧。如果是,那么将p,q标记为极点,将pq加入极边中。

解释一下这边具体的思路:对于p,q构成的边,先定义布尔类型LEmpty和REmpty为true,对其他点进行ToleftTest。如果pq是极边,那么其他点k会将LEmpty或者REmpty中的一个赋值为flase,另一个还是true。但如果pq不是极边,那么LEmpty和REmpty都会被重新赋值为flase,那么下面那个if(LEmpty || REmpty)不会执行。

实现效果如下:

 

还是用opencv绘制,这里不仅绘制了点,把极边也绘制上去了。

3. 算法策略3:decrease and conquer(减治法:减少、征服)

插入法排序:

5  1  4  2  3

(5)  1  4  2  3

(1  5) 4  2  3

(1  4  5 )2  3

(1  2  4  5 )3

(1  2  3  4  5)

策略:“减而治之,逐步蚕食”

这里凸包的构建也可以采取这一策略。先是任取三个点构成三角形作为凸包,然后从点集中取点,判断该点是否在多边形的内部/外部?如果是外部点,那就要思考插入的位置了。就这样,逐渐将剩下的点加入,最终构建好凸包。

思路:设置两个指针结构,一个就是指向点集,另一个指向极点集合(在不断变化中)。对于扫描到的点,依次连接它与极点集合的点(循环),判断其前驱和后继是否在一边,还是使用ToleftTest。如果是在一边(同为true或者同为flase),则要记录一下位置,方便后续插入;如果不在一边,就continue再判断下一个;要是都不在一边,那说明这是个内部点了。

 实现效果如下:

4.算法策略4: Jarcis March算法

凸包是首尾相连的凸多边形。根据这一特性,如果我们找到了一条极边(ki),那么就可以从这条极边出发缩小下一步查找极边的范围。如果是逆时针转的话,下一个极边从极点k出发,对其他点 l 进行搜索,如果新的 l 在kl的右侧,则更新极点。

那么如何确定最初的那个极点呢,这里采用Lowest-then-Leftmost策略,实际上是两条准则,先找最低的点(也就是y值最小的点),如果存在多个y值相同的点,那么在找那个最左的点(也就是x值最小的点)。其实这样找到的点是符合要求的,我主要是从直观感觉上来。找到这个点 ltl,下面再从它出发来寻找极边。就可以了。

 

 实现效果如下:

这篇就到这里了,思路明确了,其实代码实现就考验编程能力(当然还有很多)。课程中好像没有提供 算法策略3(减治法) 的具体实现代码,其他的都有那个最关键的思路的。我在代码实现的基础上,调用了opencv来进行了一下可视化,前提是要配好opencv的环境。OK啦,休息一下啦。

(念叨念叨)不念叨了。 

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

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

相关文章

CVE-2023-2766:泛微E-Office信息泄露漏洞复现 [附POC]

文章目录 泛微E-Office信息泄露漏洞(CVE-2023-2766)复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 泛微E-Office信息泄露漏洞(CVE-2023-2766)复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用…

成绩发布快捷方式

当一名老师&#xff0c;每到学期中期末&#xff0c;是不是觉得成绩发布就像个老大难&#xff1f;学生急着要知道自己的成绩&#xff0c;家长也频繁私信询问成绩&#xff0c;而传统的成绩发布方式却往往效率低下&#xff0c;费时费力。今天就来聊聊如何通过查询系统、各类代码、…

算法笔记-第九章-二叉树的遍历(待整理)

算法笔记-第九章-二叉树的遍历 二叉树的先序遍历二叉树的中序遍历二叉树的先序遍历 //二叉树的先序遍历 #include <cstdio> #include <vector> using namespace std;const int MAXN = 50;struct Node //用结构体表示左子树和右子树的数据 {int l, r; } nodes[MAXN]…

海康G5系列(armv7l) heop模式下交叉编译Qt qmqtt demo,出现moc缺少高版本GLibc问题之解决

1.编辑源 sudo vi /etc/apt/sources.list 2.添加高版本的源 deb http://th.archive.ubuntu.com/ubuntu jammy main #添加该行到文件 3.运行升级 sudo apt update sudo apt install libc6 4.strings /**/libc.so.6 |grep GLIBC_ 参考链接&#xff1a;version GLIBC_2.3…

【java学习—十四】反射获取一个类的父类、接口、构造方法(3)

文章目录 1. 通过反射获取一个类的父类和接口2. 反射获取一个类的构造方法2.1. 获取全部构造器 1. 通过反射获取一个类的父类和接口 使用反射可以取得&#xff1a; 实现的全部接口 public Class<?>[] getInterfaces()&#xff1a;确定此对象所表示的类或接口实现的接口…

【论文阅读】(GAN)Generative Adversarial Nets

论文地址&#xff1a;[1406.2661] Generative Adversarial Networks (arxiv.org) “GAN之父” Ian Goodfellow 发表的第一篇提出 GAN 的论文&#xff0c;这应该是任何开始研究学习 GAN 的都该阅读的一篇论文&#xff0c;它提出了 GAN 这个模型框架&#xff0c;讨论了非饱和的损…

算法——图——bsf 广度优先搜索算法 (Breadth First Search)

图遍历算法——bsf 广度优先搜索算法 &#xff08;Breadth First Search&#xff09; 算法 概述算法过程步骤一&#xff1a;初始化原点到队列步骤二&#xff1a;将队列的头顶点放入到已完成集合步骤三&#xff1a;将订单的关联顶点放入到队列中步骤四&#xff1a;将u顶点设置为…

【23真题】易,学硕爆冷,题目常规!

今天分享的是23年广州大学823的信号与系统试题及解析。广州大学23年学硕爆冷&#xff0c;一志愿全部录取&#xff0c;不知道24情况将如何。我们拭目以待&#xff01; 本套试卷难度分析&#xff1a;本套试题内容难度中等偏下&#xff0c;考察的知识点都是比较常见的&#xff0c…

不使用宝塔面板 安装 EasyImage 简单图床

发布于 2023-07-17 在 https://chenhaotian.top/linux-app/easy-image/ 前言 如果不希望安装宝塔面板或其国际版 aapanel&#xff08;尽管宝塔面板可以在安装后关闭&#xff09;&#xff0c;那么可以参考这篇文章。 本文安装环境为 Debian 11, 在 Ubuntu 20.04 测试通过 安…

【python 生成器】yield关键字,协程必知必会系列文章--自己控制程序调度,体验做上帝的感觉 1

python生成器系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 第一章 yield — Python (Part I) 文章目录 python生成器系列文章目录前言1. Generator Function 生成器函数2.并发和并行&#xff0c;抢占式和协作式2.Let’…

spring-cloud-注册中心

一、服务注册中心组件(*) 定义&#xff1a;服务注册中心就是在整个微服务架构单独抽取一个服务&#xff0c;该服务不做项目中任何业务功能&#xff0c;仅用来在微服务中记录微服务、对微服务进行健康状态检查&#xff0c;及服务元数据信息存储常用的注册中心&#xff1a;eurek…

python实现双臂老虎机k-armed-bandit

老虎机&#xff0c;投入钱币会随机返还钱币&#xff08;reward&#xff09; 这里设置两台老虎机&#xff0c;一台均值500&#xff0c;标准差5&#xff0c;一台均值550&#xff0c;标准差10 初始值均为998&#xff0c;更新规则为reward之和/轮数 最后结果会在均值附近收敛 impo…

Eigen的基操

转自博客 博客

解析SQL 获取表、字段及SQL查询参数

解析SQL 获取表、字段及SQL查询参数 1. 执行效果2. 使用2.1 引入依赖2.2 相关实体2.3 工具类 1. 执行效果 2. 使用 2.1 引入依赖 <!-- sql 解析处理--><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifa…

2022年12月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下面哪个语句正确定义了元组类型数据tuple1?( ) A: tuple1=[“张三”,“李四”,“王五”] B: tuple1=(“张三”;“李四”;“王五”) C: tuple1=(张三,李四,王五) D: tuple1=(“张三…

Mybatis-Plus最新教程

目录 原理&#xff1a;MybatisPlus通过扫描实体类&#xff0c;并基于反射获取实体类信息作为数据库信息。 ​编辑1.添加依赖 2.常用注解 3.常见配置&#xff1a; 4.条件构造器 5.QueryWrapper 6.UpdateWrapper 7.LambdaQueryWrapper:避免硬编码 8.自定义SQL 9.Iservic…

C++——友元函数

如下是一个日期类&#xff1a; class Date { public:Date(int year 2023, int month 10, int day 1){_year year;_month month;_day day;if (_month < 1 || month > 12 || _day < 1 || _day > GetMonthDay(_year, _month)){cout << "日期不规范&…

[MySQL] MySQL中的数据类型

在MySQL中&#xff0c;数据类型用于定义表中列的数据的类型。在前面的几篇文章中&#xff0c;我们也会看到有很多的数据类型&#xff0c;例如&#xff1a;char、varchar、date、int等等。本篇文章会对常见的数据类型进行详细讲解。希望会对你有所帮助&#xff01; 文章目录 一、…

[黑马程序员Pandas教程]——Pandas读取保存数据

目录&#xff1a; 学习目标读写文件 写文件读取文件 index_col参数指定索引parse_dates参数指定列解析为时间日期类型encoding参数指定编码格式读取tsv文件Pandas读写文件小结读写数据库 安装pymysql包将数据写入数据库从数据库中加载数据总结项目地址 1.学习目标 能够使用Pan…

吊打Fast Request还免费? 这款插件真心好用!

今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;比Fast Request更好用并且完全免费&#xff01;三大亮点功能&#xff1a;写完代码IDEA内一键生成API文档&#xff1b;写完代码IDEA内一键调试&#xff0c;&#xff1b;生成API目录树&#xff0c;双击即可快速…