graham 算法计算平面投影点集的凸包

文章目录

  • 向量的内积(点乘)、外积(叉乘)
    • 确定旋转方向
    • numpy 的 cross 和 outer
      • `np.inner` 向量与矩阵计算示例
      • `np.outer` 向量与矩阵计算示例
  • python 示例
    • 生成样例散点数据图
    • 显示按极角排序的结果
    • 根据排序点计算向量转向并连成凸包
  • 基本思路

将三维空间中的点云使用 BEV 的方式多视角投影到某个平面之后,可能需要用到该平面投影图(光栅化之前)的点集的凸包,所以这里记录一下常见的 graham 凸包算法。

向量的内积(点乘)、外积(叉乘)

graham 算法模拟最外层点集包围的过程的关键思想是使用两个向量之间的外积来判断下一条连线的转角,如果向外拐了,那说明当前基点在本次连线之后会成为一块凹陷,注意“凸包”的定义,每个顶角的角度都小于 18 0 ∘ 180^\circ 180 才叫 “凸” ,如果有一个内凹顶点,那么它的内角是大于 18 0 ∘ 180^\circ 180 的,可以确定,它应该是包含在实际的最终计算出来的理想凸包之内才对,这个时候就需要调整连线的基点为上一个基点。

在二维平面上,叉积的结果与向量的顺时针或逆时针旋转方向有关。具体来说:

  • 对于二维平面上的两个向量 u = ( x 1 , y 1 ) u=(x_1,y_1) u=(x1,y1) v = ( x 2 , y 2 ) v=(x_2, y_2) v=(x2,y2) ,它们的叉积可以使用一个标量值来表示 u × v = x 1 y 2 − y 1 x 2 u\times v = x_1y_2 - y_1x_2 u×v=x1y2y1x2
  • 这个标量值表示了这两个向量所定义的平行四边形的有向面积,也可以用来判定向量的旋转方向。

确定旋转方向

  • 正值:当 叉积 的值为正时,向量 v v v 从向量 u u u 逆时针旋转到达 v v v,也就是说, v v v u u u 的左侧。
  • 负值:当 叉积 的值为负时,向量 v v v 从向量 u u u 顺时针旋转到达 v v v,也就是说, v v v u u u 的右侧。
  • 零值:当 叉积 的值为零时,两个向量是共线的,即它们之间没有旋转,或者说它们之间的旋转角度是 0 ∘ 0^\circ 0∘ 或 18 0 ∘ 180^\circ 180

numpy 的 cross 和 outer

示例 python 代码:

a = np.array([1, 1])
b = np.array([0, 1])np.cross(a, b)

输出结果为 1 ,代表由向量 a 转动到向量 b 的转角是逆时针,符合右手螺旋。

numpy 库中有两个函数分别是 np.cross(a,b)np.outer(a,b) ,其中 np.cross 是我们常用所说的外积(叉乘),而 np.outer 实际的计算结果定义是一个张量中的每个元素对另一个张量中的每个元素的乘积。

np.inner 向量与矩阵计算示例

# Python Program illustrating 
# numpy.inner() method 
import numpy as np # Vectors 
a = np.array([2, 6]) 
b = np.array([3, 10]) 
print("Vectors :") 
print("a = ", a) 
print("\nb = ", b) # Inner Product of Vectors 
print("\nInner product of vectors a and b =") 
print(np.inner(a, b)) print("---------------------------------------") # Matrices 
x = np.array([[2, 3, 4], [3, 2, 9]]) 
y = np.array([[1, 5, 0], [5, 10, 3]]) 
print("\nMatrices :") 
print("x =", x) 
print("\ny =", y) # Inner product of matrices 
print("\nInner product of matrices x and y =") 
print(np.inner(x, y)) 

输出:

Vectors :
a =  [2  6]
b =  [3 10]Inner product of vectors a and b =
66
---------------------------------------Matrices :
x = [[2 3 4][3 2 9]]y = [[ 1  5  0][ 5 10  3]]Inner product of matrices x and y =
[[17 52][13 62]]

可以看到对于向量来说,外积在 numpy 中的 outer 不是我们说常说的叉乘计算方式,而是一个向量中的每个元素对另一个向量中的每个元素的乘积结果。

np.outer 向量与矩阵计算示例

# Python Program illustrating  
# numpy.outer() method  
import numpy as np # Vectors 
a = np.array([2, 6]) 
b = np.array([3, 10]) 
print("Vectors :") 
print("a = ", a) 
print("\nb = ", b) # Outer product of vectors  
print("\nOuter product of vectors a and b =") 
print(np.outer(a, b)) print("------------------------------------") # Matrices 
x = np.array([[3, 6, 4], [9, 4, 6]]) 
y = np.array([[1, 15, 7], [3, 10, 8]]) 
print("\nMatrices :") 
print("x =", x) 
print("\ny =", y) # Outer product of matrices 
print("\nOuter product of matrices x and y =") 
print(np.outer(x, y)) 

输出:

Vectors :
a =  [2  6]
b =  [3 10]Outer product of vectors a and b =
[[ 6 20][18 60]]
------------------------------------Matrices :
x = [[3 6 4][9 4 6]]y = [[ 1 15  7][ 3 10  8]]Outer product of matrices x and y =
[[  3  45  21   9  30  24][  6  90  42  18  60  48][  4  60  28  12  40  32][  9 135  63  27  90  72][  4  60  28  12  40  32][  6  90  42  18  60  48]]

这说明在 graham 凸包算法中计算两个向量的旋转方向还是需要 np.cross 而不能使用 np.outer 来计算。

python 示例

生成样例散点数据图

# Test the algorithm with an example set of points
points = [(0, 3), (1, 1), (2, 2), (4, 4), (0, 0), (1, 2), (3, 1), (3, 3)]start = min(points, key=lambda p: (p[1], p[0]))print(*zip(*points))fig1 = plt.figure()
plt.scatter(*zip(*points), color='blue')
plt.scatter(*start, color="red")
plt.show()

在这里插入图片描述

graham 算法一般以最下最左(Lowest Then Leftest)的点作为基准点,图中以红色的点作为标识。

显示按极角排序的结果

sorted_points = sorted(points, key=lambda p: (p[1] - start[1]) / (p[0] - start[0] + 1e-9), reverse=False)fig, axs = plt.subplots(2, 4)
for point, ax in zip(sorted_points, axs.flatten()):ax.scatter(*zip(*points), color="blue")ax.scatter(*start, color="red")ax.plot(*zip(*[start, point]), marker="o")
plt.show()

在这里插入图片描述

根据排序点计算向量转向并连成凸包

def cross_product(o, a, b)return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])hull = []
for p in sorted_points:while len(hull) >= 2 and cross_product(hull[-2], hull[-1], p) <= 0:hull.pop()hull.append(p)fig = plt.figure()
plt.scatter(*zip(*points), color="blue")
for i in range(len(hull)):p1 = hull[i]p2 = hull[(i + 1) % len(hull)]plt.plot([p1[0], p2[0]], [p1[1], p2[1]], 'r-')
plt.show()

在这里插入图片描述

基本思路

  1. 选取基点(最左最下)
  2. 所有点与基点形成的向量进行极角排序,从小到大
  3. 从当前点(初始时是基点 p 0 p_0 p0 p i p_i pi 出发连接极角排序好的点序列中的下一个点 p i + 1 p_{i+1} pi+1
  4. 从第一个点 p 1 p_1 p1 连接第二个点 p 2 p_2 p2 ,判断前一个向量 p 0 p 1 → \overrightarrow{p_0p_1} p0p1 与新的向量 p 1 p 2 → \overrightarrow{p_1p_2} p1p2 的转向是否是往内拐,如果是外拐的话说明这个地方会形成一个凹陷,不是凸包连线,所以弹出这个新加入的点 p 2 p_2 p2 ,准备下一个点的测试

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

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

相关文章

set、map、multiset、multimap容器介绍和常用接口使用

文章目录 前言一、set容器二、multiset三、map四、multimap 前言 1、set、map、 multiset、 multimap都是基于红黑树实现的容器。 2、set、multiset都使用头文件#include<set>,map、multimap都是使用头文件#include<map> 一、set容器 1、set容器的介绍 C标准库中的…

pytest常用命令行参数解析

简介&#xff1a;pytest作为一个成熟的测试框架&#xff0c;它提供了许多命令行参数来控制测试的运行方式&#xff0c;以配合适用于不同的测试场景。例如 -x 可以用于希望出现错误就停止&#xff0c;以便定位和分析问题。–rerunsnum适用于希望进行失败重跑等个性化测试策略。 …

【BUG】已解决:AttributeError: ‘str‘ object has no attribute ‘get‘

已解决&#xff1a;AttributeError: ‘str‘ object has no attribute ‘get‘ 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c…

C++初学者指南-5.标准库(第一部分)--标准库查找算法

C初学者指南-5.标准库(第一部分)–标准库查找算法 文章目录 C初学者指南-5.标准库(第一部分)--标准库查找算法查找/定位一个元素findfind_iffind_if_notfind_last / find_last_if / find_last_if_notfind_first_of 查找范围内的子范围 search find_endstarts_withends_with 找到…

SpringBoot3 + Vue3 学习 Day 2

登入接口 和 获取用户详细信息的开发 学习视频登入接口的开发1、登入主逻辑2、登入认证jwt 介绍生成 JWT① 导入依赖② 编写代码③ 验证JWT 登入认证接口的实现① 导入 工具类② controller 类实现③ 存在的问题及优化① 编写拦截器② 注册拦截器③ 其他接口直接提供服务 获取用…

Web3D:WebGL为什么在渲染性能上输给了WebGPU。

WebGL已经成为了web3D的标配&#xff0c;市面上有N多基于webGL的3D引擎&#xff0c;WebGPU作为挑战者&#xff0c;在渲染性能上确实改过webGL一头&#xff0c;由于起步较晚&#xff0c;想通过这个优势加持&#xff0c;赶上并超越webGL仍需时日。 贝格前端工场为大家分享一下这…

Webstorm-恢复默认UI布局

背景 在使用Webstorm的时候,有时候进行个性化设置,如字体、界面布局等. 但是设置后的效果不理想,想要重新设置回原来的模样,却找不到设置项. 这里提供一种解决方案,恢复默认设置,即恢复到最初刚下载好后的设置. 操作步骤 步骤一:打开setting 步骤二:搜索Restore Default,找到…

数学建模-----SPSS参数检验和非参数检验

目录 1.参数检验 1.1独立样本t检验案例分析 1.1.1查看数据编号 1.1.2确定变量所属类型 1.1.3选项里面的置信区间 1.1.4对于结果进行分析 1.2配对样本t检验案例分析 1.2.1相关设置 1.2.2分析结果 2.非参数检验 2.1对比分析 2.2非参数检验的方法 2.3案例分析 2.3.1相…

10道JVM经典面试题

1、 JVM中&#xff0c;new出来的对象是在哪个区&#xff1f; 2、 说说类加载有哪些步骤&#xff1f; 3、 JMM是什么&#xff1f; 4、 说说JVM内存结构&#xff1f; 5、 MinorGC和FullGC有什么区别&#xff1f; 6、 什么是STW? 7、 什么情况下会发生堆/栈溢出&#xff1f…

当“广撒网”遇上“精准定点”的鱼叉式网络钓鱼

批量网络钓鱼电子邮件活动倾向于针对大量受众&#xff0c;它们通常使用笼统的措辞和简单的格式&#xff0c;其中不乏各种拼写错误。而有针对性的攻击往往需要付出更大的努力&#xff0c;攻击者会伪装成雇主或客户向目标发送包含个人详细信息的个性化消息。在更大范围内采用这种…

大语言模型-文本检索任务基准 BEIR

BEIR (A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models) 文本检索任务的基准&#xff0c;使用18 个数据集为检索系统的零样本评估提出了一个标准化基准&#xff0c; BEIR 基准上在9个不同领域的检索任务评估 10 种不同的检索方法。 九个…

义务外贸wordpress独立站主题

健身器材wordpress网站模板 跑步机、椭圆机、划船机、动感单车、健身车、深蹲架、龙门架、健身器材wordpress网站模板。 https://www.jianzhanpress.com/?p4251 农业机械wordpress网站模板 植保机械、畜牧养殖机械、农机配件、土壤耕整机械、农业机械wordpress网站模板。 …

2.1.卷积层

卷积 ​ 用MLP处理图片的问题&#xff1a;假设一张图片有12M像素&#xff0c;那么RGB图片就有36M元素&#xff0c;使用大小为100的单隐藏层&#xff0c;模型有3.6B元素&#xff0c;这个数量非常大。 识别模式的两个原则&#xff1a; 平移不变性&#xff08;translation inva…

K8S 部署jaeger-operator,与其演示项目hotrod

最近在研究observabilty在K8S环境的onboard&#xff0c;查阅了一些资料&#xff0c;发现现在网上Prometheus/Metrics相关的资源&#xff0c;是比较全面的&#xff0c;而Trace相关的部分不是很全面&#xff0c;所以写下这篇博文&#xff0c;以做备忘和分享。 组件介绍 我这里选…

Excel的操作

Excel的操作 一、Excel的作用 Excel是一款功能强大的电子表格软件&#xff0c;主要用于数据处理和分析。 二、Excel的基础操作 新建文档 一般情况下&#xff0c;就在桌面空白处&#xff0c;点击鼠标右键&#xff0c;即可新建 三、页面布局 1、快速访问工具栏 主要包含&am…

为 android编译 luajit库、 交叉编译

时间&#xff1a;20200719 本机环境&#xff1a;iMac2017 macOS11.4 参考: 官方的文档&#xff1a;Use the NDK with other build systems 写在前边&#xff1a;交叉编译跟普通编译类似&#xff0c;无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Make…

ssm 学习 ---(spring)

一、spring框架 1、基本框架 2、Beanfactory快速入门 配置清单&#xff1a;xml文件 (1) 导入jar包或者maven坐标 (2) 定义UserService接口以及UserService实现类 (3) 创建bean.xml配置文件&#xff0c;将UserService信息配置到该xml文件中; (4)编写测试代码&#xff0c;创…

ubuntu lxqt触摸屏旋转校准(usb触摸屏、lxqt、ubuntu23.10)

参考文章&#xff1a;https://www.codetd.com/article/5651388 1.查看触摸屏驱动 rootxyy:~# xinput list ⎡ Virtual core pointer id2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id4 [slave pointer (2)…

如何根据同一行的ID利用R语言对值进行求和

需求&#xff1a;将属于同一分组的对应的值进行求和或者求平均值 #设置工作目录 > getwd() [1] "C:/Users/86150/Documents" > setwd("C:/Users/86150/Desktop/AA2024/RUF") > list.files() #读取文件 >install.packages("readxl")…

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS

基于NeRF的路面重建算法——RoME / EMIE-MAP / RoGS 1. RoMe1.1 Mesh Initialization / Waypoint Sampling1.2 Optimization1.3 Experiments 2. EMIE-MAP2.1 Road Surface Representation based on Explicit mesh and Implicit Encoding2.2 Optimizing Strategies2.3 Experimen…