给定n个点或一个凸边形,求其最小外接矩形,可视化
这里写目录标题
- 原理
- 代码
原理
-
求n个点的最小外接矩形问题可以等价为先求这n个点的凸包,再求这个凸包的最小外接矩形。
其中求凸包可以使用Graham-Scan算法
需要注意的是,
因为Graham-Scan算法要求我们从先找到凸包上的一个点,所以我们可以先对这些点进行排序,根据x/y坐标都可以。排序后的第一个点和最后一点一定在凸包上。
同时,假设我们按照x排序,并且想要得到顺时针旋转的凸包边界,那么我们只能找到一半的边界,这是因为我们从左到右遍历这些点的时候只有上面的点才满足顺时针,下面的不可能满足顺时针(这里为了节省计算可以只对y坐标大于开始和结束点中最小y坐标的点进行计算)。
为了找到全部的点,我们需要正向判断完后再反向相同方法判断一遍。
这里为了判断是顺时针还是逆时针,我们使用的是两个方向叉乘的最后一项,从前一个方向转到后一个方向时:如果叉乘最后一项小于0,说明是顺时针旋转的(右手系)。

-
给定一个凸多边形,求最小外接矩形的原理可以参考这篇博客https://blog.csdn.net/wang_heng199/article/details/74477738
简单而言就是对凸包上的每条边构造矩形并比较面积。
我们这里的做法是遍历每条边,对于每条边,我们根据它与水平方向的夹角计算其旋转矩阵,并将这些凸包上的所有点根据此旋转矩阵的逆矩阵/转置矩阵(旋转矩阵是正交矩阵)旋转至水平方向,此时我们可以很容易得到这些点水平方向和竖直方向的边界点,从而就有了一个外接矩形。
代码
导入包并且初始化随机点:
import numpy as np
import matplotlib.pyplot as plt
n = 100
points = np.random.randn(n, 2)
计算凸包并可视化
sorted_points = points[np.argsort(points[:,0])]def cal_rotate_orientation(cur,stack_end,stack_end_before):'''计算p1->p2的向量旋转到p2->p3的向量是顺时针还是逆时针'''p1,p2,p3 = sorted_points[stack_end_before], sorted_points[stack_end], sorted_points[cur]x2,y2 = p3 - p2x1,y1 = p2 - p1return x1*y2 - x2*y1 #叉乘最后一项Z轴方向,<0:顺时针,>0:逆时针def cal_convex_hull(index_list):result = list(index_list[:2])index_list = index_list[2:]for i in index_list:if (cal_rotate_orientation(i,result[-1],result[-2]) < 0): #叉乘最后一项 ,符合顺时针# print(i,result[-1],result[-2])result.append(i)else:if len(result) == 2: result[-1] = i continueresult.pop()while(cal_rotate_orientation(i,result[-1],result[-2]) > 0): #不是顺时针,需要反复剔除result.pop()if len(result) < 2:breakresult.append(i)return result#n-1是最后一个点,因为它肯定在第一遍的结果里,所以两个结果合并时去除第一个
result = cal_convex_hull(range(0,n,1))+cal_convex_hull(range(n-1,-1,-1))[1:]
print(result)
#ploy是将结果按照顺序两两组合,形成边界
ploy = list(map(lambda i:result[i:i+2],range(0,len(result)-1)))plt.scatter(sorted_points[:, 0], sorted_points[:, 1])
plt.plot(sorted_points[result,0],sorted_points[result,1],color = 'red')
plt.show()

计算最小外接矩形
这里为了可视化,我们会将矩形转回来。
def get_rotate(cos,sin):#我们已知在原坐标系下的方向,要将其转化到目标系,用逆/转置return np.array([[cos,-sin],[sin,cos]]) def get_rotate2(theta):#我们已知在原坐标系下的方向,要将其转化到目标系,用逆/转置return np.array([[np.cos(theta),-np.sin(theta)],[np.sin(theta),np.cos(theta)]])row = 3
col = (len(ploy)+1)//3+1
fig, axs = plt.subplots(row, col, figsize=(15, 15))min_rect = [[],0,np.inf] #rect,angle,area
#假设是-90度 -> 90度
for idx, (i,j) in enumerate(ploy):x1,y1 = sorted_points[i]x2,y2 = sorted_points[j]tan_theta = (y2-y1)/(x2-x1)cos_theta = np.sqrt(1/(1+np.power(tan_theta,2)))sin_theta = cos_theta*tan_thetarotated_points = sorted_points@get_rotate(cos_theta,sin_theta)min_x,min_y = np.min(rotated_points,axis=0)max_x,max_y = np.max(rotated_points,axis=0)rect_xy = np.array([[min_x,min_y],[max_x,min_y],[max_x,max_y],[min_x,max_y]])rect_area = (max_x-min_x)*(max_y-min_y)if rect_area < min_rect[2]:min_rect = [rect_xy,np.arcsin(-sin_theta),rect_area] #这个角度是取反,因为要转回去rect_xy = rect_xy@get_rotate(cos_theta,-sin_theta) #转一下axs[idx//col,idx%col].scatter(points[:, 0], points[:, 1])plot_idx = [i for i in range(0,4)]+[0]axs[idx//col,idx%col].plot(rect_xy[plot_idx,0],rect_xy[plot_idx,1],color = 'orange')axs[idx//col,idx%col].set_xlim(-4,4)axs[idx//col,idx%col].set_ylim(-4,4)axs[idx//col,idx%col].set_aspect('equal')rect_xy = min_rect[0]@get_rotate2(min_rect[1])axs[(idx+1)//col,(idx+1)%col].scatter(points[:, 0], points[:, 1])
plot_idx = [i for i in range(0,4)]+[0]
axs[(idx+1)//col,(idx+1)%col].plot(rect_xy[plot_idx,0],rect_xy[plot_idx,1],color = 'red')
axs[(idx+1)//col,(idx+1)%col].set_xlim(-4,4)
axs[(idx+1)//col,(idx+1)%col].set_ylim(-4,4)
axs[(idx+1)//col,(idx+1)%col].set_aspect('equal')
plt.show()

相关文章:
给定n个点或一个凸边形,求其最小外接矩形,可视化
这里写目录标题 原理代码 原理 求n个点的最小外接矩形问题可以等价为先求这n个点的凸包,再求这个凸包的最小外接矩形。 其中求凸包可以使用Graham-Scan算法 需要注意的是, 因为Graham-Scan算法要求我们从先找到凸包上的一个点,所以我们可以先…...
蓝桥杯每日一题2023.11.6
取位数 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 由题意我们知道len中为现阶段长度,如果其与k相等也就是找到了正确的位数,否则就调用递归来进行搜索,每次搜索一位数。 #include <stdio.h> // 求x用10进制表示时的数位长度 int …...
V-REP和Python的联合仿真
机器人仿真软件 各类免费的的机器人仿真软件优缺点汇总_robot 仿真 软件收费么_dyannacon的博客-CSDN博客 课程地址 https://class.guyuehome.com/p/t_pc/course_pc_detail/column/p_605af87be4b007b4183a42e7 课程资料 guyueclass: 古月学院课程代码 旋转变换 旋转的左乘与…...
WPF布局控件之DockPanel布局
前言:博主文章仅用于学习、研究和交流目的,不足和错误之处在所难免,希望大家能够批评指出,博主核实后马上更改。 概述: DockPanel 位置子控件基于子 Dock 属性,你有 4 个选项停靠,左 (默认) &…...
【实战Flask API项目指南】之二 Flask基础知识
实战Flask API项目指南之 Flask基础知识 本系列文章将带你深入探索实战Flask API项目指南,通过跟随小菜的学习之旅,你将逐步掌握Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧! 前言 当小菜踏入Flask后端开发的世界&…...
Linux 编译链接那些事儿(02)C++链接库std::__cxx11::basic_string和std::__1::basic_string链接问题总结
1 问题背景说明 在自己的项目源码中引用libeasysqlite.so时编译成功,但运行时遇到问题直接报错,找不到符号 symbol:_ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEi。 2 问题描述和解…...
按键精灵中的UI界面操作
1. 按键精灵中UI界面常用的控件 1. 文字框 界面1: {标签页1:{文字框:{名称:"文字框1",显示内容:"显示内容",文字大小:0,高度:0,宽度:0,注释:"文字大小、高度、宽度是可选属性,如需使用默认值,可保持值为0或直接删除此属性&qu…...
dpdk 程序如何配置网卡收发包队列描述符配置?
问题描述 dpdk 程序在配置网卡队列时会涉及收发包队列描述符数量配置问题,收发包描述符的数量看似是一个简单的配置,却对转发性能有着一定的影响。实际业务程序中,收发包描述符大小配置一般参考 dpdk 内部示例程序配置进行,经验之…...
二蛋赠书七期:《云原生数据中台:架构、方法论与实践》
前言 大家好!我是二蛋,一个热爱技术、乐于分享的工程师。在过去的几年里,我一直通过各种渠道与大家分享技术知识和经验。我深知,每一位技术人员都对自己的技能提升和职业发展有着热切的期待。因此,我非常感激大家一直…...
计算机毕设 基于大数据的服务器数据分析与可视化系统 -python 可视化 大数据
文章目录 0 前言1 课题背景2 实现效果3 数据收集分析过程**总体框架图****kafka 创建日志主题****flume 收集日志写到 kafka****python 读取 kafka 实时处理****数据分析可视化** 4 Flask框架5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升&a…...
初识rust
调试下rust 的执行流程 参考: 认识 Cargo - Rust语言圣经(Rust Course) 新建一个hello world 程序: fn main() {println!("Hello, world!"); }用IDA 打开exe,并加载符号: 根据字符串找到主程序入口: 双击…...
shiro-cve2016-4437漏洞复现
一、漏洞特征 Apache Shiro是一款开源强大且易用的Java安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。 因为在反序列化时,不会对其进行过滤,所以如果传入恶意代码将会造成安全问题 在 1.2.4 版本前, 加…...
【MongoDB-Redis-MySQL-Elasticsearch-Kibana-RabbitMQ-MinIO】Java全栈开发软件一网打尽
“Java全栈开发一网打尽:在Windows环境下探索技术世界的奇妙之旅” 前言 全栈开发是一项复杂而令人兴奋的任务,涵盖了从前端到后端、数据库到可视化层、消息队列到文件存储的广泛领域。本文将带您深入探讨在Windows环境下进行全栈开发的过程࿰…...
Implementing class错误解决
最近在使用IDEASmart Tomcat启动项目时,报以下错误: Injection of resource dependencies failed; nested exception is java.lang.IncompatibleClassChangeError: Implementing class根据网上结论加上我这里的原因,总共以下几个方面&#x…...
关于 国产系统UOS系统Qt开发Tcp服务器外部连接无法连接上USO系统 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/134254817 红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…...
初阶JavaEE(15)(Cookie 和 Session、理解会话机制 (Session)、实现用户登录网页、上传文件网页、常用的代码片段)
接上次博客:初阶JavaEE(14)表白墙程序-CSDN博客 Cookie 和 Session 你还记得我们之前提到的Cookie吗? Cookie是HTTP请求header中的一个属性,是一种用于在浏览器和服务器之间持久存储数据的机制,允许网站…...
C++入门学习(1)命名空间和输入输出
前言 在C语言和基本的数据结构学习之后,我们终于迎来了期待已久的C啦!C发明出来的意义就是填补一些C语言的不足,让我们更加方便的写代码,所以今天我们就来讲一下C语言不足的地方和在C中的解决办法! 一、命名空间 在学习…...
AI:58-基于深度学习的猫狗图像识别
🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…...
【原创】java+swing+mysql宠物领养管理系统设计与实现
摘要: 生活中,有很多被人遗弃的宠物,这些宠物的处理成为了一个新的难题。生活中也有许多人喜欢养宠物,为了方便大家进行宠物领养,提高宠物领养管理的效率和便利性。本文针对这一问题,提出设计和实现一个基…...
虚拟机Linux-Centos系统网络配置常用命令+Docker 的常用命令
目录 1、虚拟机Linux-Centos系统网络配置常用命令2、Docker 的常用命令2.1 安装docker步骤命令2.2 在docker容器中安装和运行mysql 2、dockerfile关键字区别(ADD/COPY,CMD/ENTRYPOINT) 1、虚拟机Linux-Centos系统网络配置常用命令 进入网络配置文件目录 cd /etc/sysconfig/ne…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
