Andrew算法求凸包模板

前置知识

向量的叉乘: 设 a ⃗ = ( x a , y a , z a ) , b ⃗ = ( x b , y b , z b ) \vec a=(x_a,y_a,z_a), \vec b=(x_b, y_b,z_b) a =(xa,ya,za),b =(xb,yb,zb), 令 a ⃗ \vec a a b ⃗ \vec b b 的叉乘为 c ⃗ \vec c c , 有:
c ⃗ = ∣ i j k x a y a z a x b y b z b ∣ = ( y a z b − z a y b , z a x b − x a z b , x a y b − y a x b ) \vec c=\begin{vmatrix} i & j & k\\ x_a & y_a & z_a\\ x_b & y_b & z_b \end{vmatrix}=(y_az_b-z_ay_b,z_ax_b-x_az_b,x_ay_b-y_ax_b) c = ixaxbjyaybkzazb =(yazbzayb,zaxbxazb,xaybyaxb)
几何意义: ∣ c ⃗ ∣ = ∣ a ⃗ × b ⃗ ∣ = ∣ a ⃗ ∣ ∣ b ⃗ ∣ s i n θ |\vec c|=|\vec a×\vec b|=|\vec a| |\vec b|sin\theta c =a ×b =a ∣∣b sinθ ( θ \theta θ a ⃗ \vec a a b ⃗ \vec b b 向量之间的夹角), 即 ∣ c ⃗ ∣ |\vec c| c 等于 a ⃗ \vec a a , b ⃗ \vec b b 向量构成的平行四边形的面积.
另外 c ⃗ \vec c c 的方向可以用右手螺旋定则判定: 先将 a ⃗ \vec a a b ⃗ \vec b b 移动到同一起点, 右手四指从 a ⃗ \vec a a 方向朝掌心方向旋转到 b ⃗ \vec b b 方向, 则拇指所指方向, 即为结果向量的方向.
在这里插入图片描述

PIP 问题

理解了上述的叉乘的知识, 我们就可以解决PIP这个经典问题的一个子集: 判断一个点是否在一个凸多边形内部. 判断算法的一个伪代码如下:

p 0 , ⋯ , p n − 1 p_0,\cdots,p_{n-1} p0,,pn1为凸多边形边界上的点按逆时针方向遍历形成的一个排列, x x x为待判断的点
for i i i in { 0 , ⋯ , n − 1 } \{0,\cdots,n-1\} {0,,n1}
\;\;\;\; ( p i p ( i + 1 ) % n → × p ( i + 1 ) % n x → ) ⋅ ( 0 , 0 , 1 ) < 0 (\overrightarrow{p_ip_{(i+1)\%n}} \times \overrightarrow{p_{(i+1)\%n}x})\cdot (0,0,1)<0 (pip(i+1)%n ×p(i+1)%nx )(0,0,1)<0, 则 x x x不在多边形内部
x x x在多边形内部(包括边界上)

求凸包

上面提到的伪代码需要凸多边形边界上的点的一个逆时针的排列, 但如过这个排列没有给出, 这时候就可以用Andrew凸包算法来求这样的一个排列, Andrew算法大致思想如下:

首先把所有点以横坐标为第一关键字,纵坐标为第二关键字排序。显然排序后最小的元素和最大的元素一定在凸包上。而且因为是凸多边形,我们如果从一个点出发逆时针走,轨迹总是「左拐」的,一旦出现右拐,就说明这一段不在凸包上。因此我们可以用一个单调栈来维护上下凸壳。

下面贴一个Andrew算法的模板

inline pair<int, int> vec_ab(pair<int, int> a, pair<int, int> b) {return {b.first - a.first, b.second - a.second};
}inline int cross_prod(pair<int, int> a, pair<int, int> b) {return a.first * b.second - a.second * b.first;
}const int maxn = 2e5 + 5;
pair<int, int> p[maxn], h[maxn];
int stk[maxn];
int used[maxn];int main() {
// stk[] 是整型,存的是下标int n;int tp=0 // 初始化栈//读入pstd::sort(p + 1, p + n + 1);  // 对点进行排序stk[++tp] = 1;
// 栈内添加第一个元素,且不更新 used,使得 1 在最后封闭凸包时也对单调栈更新for (int i = 2; i <= n; ++i) {while (tp >= 2 && cross_prod(vec_ab(p[stk[tp - 1]], p[stk[tp]]), vec_ab(p[stk[tp]], p[i])) < 0)//凸包边上的点不算在结果数组内(否则用<0)used[stk[tp--]] = 0;used[i] = 1;  // used 表示在凸壳上stk[++tp] = i;}int tmp = tp;  // tmp 表示下凸壳大小for (int i = n - 1; i > 0; --i)if (!used[i]) {// ↓求上凸壳时不影响下凸壳while (tp > tmp && cross_prod(vec_ab(p[stk[tp - 1]], p[stk[tp]]), vec_ab(p[stk[tp]], p[i])) < 0)//凸包边上的点不算在结果数组内(否则用<0)used[stk[tp--]] = 0;used[i] = 1;stk[++tp] = i;}for (int i = 1; i < tp; ++i)  // 复制到新数组中去h[i] = p[stk[i]];int ans = tp - 1; // ans为凸包边上节点数

参考:
https://oi-wiki.org/geometry/convex-hull/
https://zhuanlan.zhihu.com/p/385131501

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

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

相关文章

【深度学习】GPT-3

2020年5月&#xff0c;OpenAI在长达72页的论文《https://arxiv.org/pdf/2005.14165Language Models are Few-Shot Learners》中发布了GPT-3&#xff0c;共有1750亿参数量&#xff0c;需要700G的硬盘存储&#xff0c;(GPT-2有15亿个参数)&#xff0c;它比GPT-2有了极大的改进。根…

钉钉返回:访问ip不在白名单之中,请参考FAQ

新版钉钉 在开发管理-服务器出口IP-配置返回错误信息返回给你的requestIp

k8s部署新版elasticsearch+kibana并配置快照备份

版本:es 7.17.6 kibana 7.17.6 k8s:1.19.16 一、介绍 Elasticsearch和Kibana是一对强大的开源工具&#xff0c;通常一起使用以构建实时数据分析和可视化解决方案。 Elasticsearch: Elasticsearch是一个分布式、高性能的实时搜索和分析引擎。它构建在开源搜索引擎库Lucene之上…

【C++】开源:Redis数据库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Redis数据库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

边缘计算对现代交通的重要作用

边缘计算之所以重要&#xff0c;是在于即使在5G真正商用之时&#xff0c;可以实现超大带宽&#xff08;eMBB&#xff09;的应用场景&#xff0c;但庞大数据量的涌现也就意味着需要在云和端传输过程中找到一个承接点&#xff0c;对数据进行预处理再选择是否上云。 边缘计算应用演…

【Python入门【推导式创建序列、字典推导式、集合推导式】(九)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

SkyWalking链路追踪-技术文档首页

SkyWalking 文档中文版&#xff08;社区提供&#xff09; (skyapm.github.io)https://skyapm.github.io/document-cn-translation-of-skywalking/ SkyWalking-基本概念 SkyWalking链路追踪是一个用于分布式系统的性能监控工具&#xff0c;它帮助开发人员了解系统中各组件之间…

工程安全监测无线振弦采集仪在建筑物的应用分析

工程安全监测无线振弦采集仪在建筑物的应用分析 工程安全监测无线振弦采集仪是一种在建筑物中应用的重要设备。它通过无线采集建筑物内部的振动信息&#xff0c;对建筑物的安全性进行监测和评估&#xff0c;为建筑物的施工和使用提供了可靠的技术支持。本文将详细介绍工程安全…

ElasticSearch基础篇-安装与基本操作

ElasticSearch基础篇 安装 官网 下载地址 下载完成后对文件进行解压&#xff0c;项目结构如下 进入bin目录点击elasticsearch.bat启动服务 9300 端口为 Elasticsearch 集群间组件的通信端口&#xff0c; 9200 端口为浏览器访问的 http协议 RESTful 端口 打开浏览器&#…

力扣热门100题之矩阵置0【中等】

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例 2&#xff…

C++ - list介绍 和 list的模拟实现

list介绍 list 是一个支持在常数范围内&#xff0c;任意位置进行插入删除的序列式容器&#xff0c;且这个容器可以前后双向迭代。我们可以把 list 理解为 双向循环链表的结构。 于其他结构的容器相比&#xff0c;list在 任意位置进行插入和函数的效率要高很多&#xff1b;而li…

SWF格式视频怎么转换成AVI格式?简单的转换方法分享

当你想要在不同的设备上播放视频时&#xff0c;将SWF格式视频转换成AVI格式是非常有用的。因为SWF格式通常只能在特定的软件或网页上播放&#xff0c;而AVI格式则可以在更广泛的设备上播放&#xff0c;包括智能手机&#xff0c;平板电脑和电视机等。那么我们怎么将SWF转换成AVI…

AI学习笔记四:yolov5训练自己的数据集

若该文为原创文章&#xff0c;转载请注明原文出处。 一般情况下&#xff0c;大部分人的电脑都是没有cpu的&#xff0c;cpu也是可以训练的&#xff0c;但花费的时间太长&#xff0c;实际200张图片&#xff0c;使用CPU训练300轮花了3天&#xff0c;本章记录使用云服务器来训练自…

SkyWalking链路追踪-搭建-spring-boot-cloud-单机环境 之《10 分钟快速搭建 SkyWalking 服务》

首先了解一下单机环境 第一步&#xff0c;搭建一个 Elasticsearch 服务。第二步&#xff0c;下载 SkyWalking 软件包。第三步&#xff0c;搭建一个 SkyWalking OAP 服务。第四步&#xff0c;启动一个 Spring Boot 应用&#xff0c;并配置 SkyWalking Agent。第五步&#xff0c;…

Docker Compose 容器编排

Docker compose Docker compose 实现单机容器集群编排管理&#xff08;使用一个模板文件定义多个应用容器的启动参数和依赖关系&#xff0c;并使用docker compose来根据这个模板文件的配置来启动容器&#xff09; 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…

【小白学编程5】我的房子在哪儿?理解类型和变量

我的房子在哪儿? 理解类型和变量 - 《小白学编程》系列第五讲 - 《小白学编程》系列课程过半&#xff0c;为满足更多同学的时间需求&#xff0c;课程直播时间改为了晚上八点。 昨晚八点准时开始课程的第五讲&#xff0c;其主题为&#xff1a;“我的房子在哪儿&#xff1f;理解…

学习 C语言第二天 :C语言数据类型和变量(下)

目录&#xff1a; 1.变量的介绍以及存储 2.算术操作符、赋值操作符、单目操作符 3.scanf和printf的介绍 1.变量的介绍以及存储 1.1.变量的创建 了解了什么是类型了&#xff0c;类型是用来创建变量的。 变量是什么呢&#xff1f;在C语言当中不经常变的量称为常量&#xff0c;经常…

【雕爷学编程】Arduino动手做(95)---GY9960手势传感器模块3

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

直播平台源码开发提高直播质量的关键:视频编码和解码技术

在互联网日益发展的今天&#xff0c;直播平台成为人们互联网生活的主力军&#xff0c;直播平台功能的多样化与智能化使我们的生活有了极大地改变&#xff0c;比如短视频功能&#xff0c;它让我们既可以随时随地去发布自己所拍摄到的东西让世界各地的用户看到&#xff0c;也能让…

Windows下基于VSCode搭建C++开发环境(包含整合MinGW64、CMake的详细流程)

最近想写写C&#xff0c;装了VisualStudio 2022&#xff0c;折腾半天。对于一个用惯VSCode的人来说&#xff0c;总感觉IDE太笨重。于是自己网上各种查资料&#xff0c;自己琢磨&#xff0c;搭建了一套Windows下基于VSCode和CMake的C轻量级开发环境。 具体搭建步骤 1. 下载并安…