旋转卡壳算法求最小外接矩形代码
旋转卡壳原理:旋转卡壳详解_大学要有梦想的博客-CSDN博客_旋转卡壳
思路:
1.选择卡壳算法用于求凸多边形的最小外接矩形
1.多边形最小的外接矩形一定是以多边形的的一条边为底的一部分
2.通过这条边算出以这条边为底的最上点、最右点和最左点。然后算出以这条边为底的矩形面积
重点:
计算最上点的原理是:
利用到向量叉积求面积的原理,因为求凸包前,所有点是按角度顺序排列好的,向量叉积代表两向量围成的矩形面积,底边不变,高越大,则面积越大,而因为点是按角度排序,所以面积会先变大,后变小,在突然变小的那个地方,说明那个点是最上点。
计算最右点的原理是:
利用向量求点积投影的原理,由于是凸包且点是按角度顺序排列好的,用第一条边对底边投影的大小减第二条边对底边投影的大小,一旦变成正的,说明点是最右点。
计算最左点的原理是:
利用向量求点积投影的原理,由于是凸包且点是按角度顺序排列好的,以最右点那个点作为左起始点计算,用第一条边对底边投影的大小减第二条边对底边投影的大小,一旦变成负的,说明点是最左点。
3.最终通过计算以多边形其他边为底的矩形面积,如果比较全部矩形面积,最小的那个就是外接矩形。
代码:
/**MABR:Minimum Area Bounding Rectangle* @brief :获取由凸包传来的点集,计算最小外接矩形,采用旋转卡壳算法* @param[in] :凸包传来的点集,逆时针顺序的点集* @param[out] :* @return :返回最小外接矩形的四个点集。顺时针方向*/CUBECOM_API vector<iCoord2d> GetMABRByRotatingCaliper(vector<iCoord2d>& points, double eps = 1.0e-6);//平面向量叉积double Vec2dCross(const iVec2d& fvec, const iVec2d& svec){return fvec[0] * svec[1] - fvec[1] * svec[0];}//平面向量点积double Vec2dDot(const iVec2d& fvec, const iVec2d& svec){return fvec[0] * svec[0] + fvec[1] * svec[1];}//点顺着给定的向量偏移scale距离void GetPointByVecAndScale(iCoord2d& pt, iVec2d vec, const double scale){ //归一化vec.NormalizeSelf();vec *= scale;pt += vec;}CUBECOM_API vector<iCoord2d> CubeHelper::GetMABRByRotatingCaliper(vector<iCoord2d> &points, double eps/* = 1.0e-6*/){//归一化auto cmpFunc = [=](double x) {if (fabs(x) < eps)return 0;return x > 0 ? 1 : -1;};//初始化用1e18,表示一个大值double min_s = 1e18;size_t ptSize = points.size();//首尾连接points.push_back(points[0]);//左上、左下、右上、右下iCoord2d luPt, ldPt, ruPt, rdPt;int upPt = 1, rightPt = 1, leftPt = 1;for (size_t i = 0; i < ptSize; ++i){// 最上面的点,利用叉积求面积,凸包中的点是顺序的,所以以其中一条边为底,// 面积会出现由小变大再变小,会出现最高点。while (cmpFunc(fabs(CubeHelper::Vec2dCross(points[upPt] - points[i], points[i + 1] - points[i])) -fabs(CubeHelper::Vec2dCross(points[upPt + 1] - points[i], points[i + 1] - points[i]))) <= 0){upPt = (upPt + 1) % ptSize;}// 最右边的点,利用点积的投影,向右边投影越大,凸包中的点是顺序的,// 每次相减,由负变正瞬间,说明是相对于这条边最右边的点while (cmpFunc(CubeHelper::Vec2dDot(points[rightPt] - points[i], points[i + 1] - points[i]) -CubeHelper::Vec2dDot(points[rightPt + 1] - points[i], points[i + 1] - points[i])) <= 0){rightPt = (rightPt + 1) % ptSize;}if (!i)leftPt = rightPt;// 最左边的点利用点积的投影,向左边投影越大,凸包中的点是顺序的,// 每次相减,由正变负瞬间,说明是相对于这条边最左边的点while (cmpFunc(CubeHelper::Vec2dDot(points[leftPt] - points[i], points[i + 1] - points[i]) -CubeHelper::Vec2dDot(points[leftPt + 1] - points[i], points[i + 1] - points[i])) >= 0){leftPt = (leftPt + 1) % ptSize;}//获取底边的长度double dis = points[i].DistPtPt(points[i + 1]);if (dis==0.0) continue;//获取矩形长度,通过点积求投影/底边double R = CubeHelper::Vec2dDot(points[rightPt] - points[i], points[i + 1] - points[i]) / dis;double L = CubeHelper::Vec2dDot(points[leftPt] - points[i], points[i + 1] - points[i]) / dis;double length = R - L;//获取矩形高度,通过叉积求三角形面积/底边double height = fabs(CubeHelper::Vec2dCross(points[upPt] - points[i], points[i + 1] - points[i])) / dis;double rectArea = length * height;if (rectArea < min_s){min_s = rectArea;//右下点 rdPt = points[i] + (points[i + 1] - points[i]) * (R / dis);//右上点ruPt = rdPt + (points[rightPt] - rdPt) * (height / points[rightPt].DistPtPt(rdPt));//左上点luPt = ruPt + (points[i] - rdPt) * (length / R);//左下点ldPt = luPt + (rdPt - ruPt);}}//存储矩形四个点vector<iCoord2d> rectPts {ldPt, luPt, ruPt, rdPt};return rectPts;}
旋转卡壳算法求最小外接矩形代码相关推荐
- python外包凹多边形生成_Python实现图片查找轮廓、多边形拟合、最小外接矩形代码...
1.概述 经常用到轮廓查找和多边形拟合等opencv操作,因此记录以备后续使用.本文代码中的阈值条件对图片没有实际意义,仅仅是为了测试. 原图为: 2.测试代码: import cv2 import ...
- 【OpenCV】 外接矩形、最小外接矩形、多边形拟合、外接圆
任务:给定这样一张图片求图片中白色区域的外接矩形.最小外接矩形.拟合多边形以及外接圆 1.外接矩形 x, y, w, h = cv2.boundingRect(points) 输入:点集 返回值:左上 ...
- 遍历图像 找最小外接矩形 matlab,2018a版本MatLab利用regionprops函数获取图片中物体轮廓最小外接矩形...
2018a版本MatLab利用regionprops函数获取图片中物体最小外接矩形 本次内容,用于介绍利用matlab中的regionprops函数来获取图像区域中的物体的最小外接矩形信息(位置(x, ...
- python如何做四象图_Python使用四个坐标点来剪切图像目标区域的最小外接矩形,python,利用,对,图片,进行,裁剪...
在图像裁剪操作中,opencv和pillow两个库都具有相应的函数,但是这两个库中的函数仅仅能对与图片平行的矩形进行裁剪操作,如果想要对目标的最小外接矩形进行裁剪该如何操作呢?如下所示: 具体处理该问 ...
- CGAL求最小外包矩形
有两种所谓的最小外包矩形,第一种通过求所有节点的最小与最大xy来求的,这种叫与坐标轴平行的最小外包矩形:另外一种则是本文说的这种,与范围的形状与走势有关的,叫非坐标轴平行的最小外包矩形,效果如下图所示 ...
- UVA10173(求凸包的面积最小外接矩形)
题目:10173 - Smallest Bounding Rectangle 求凸包的最小外接矩形的面积. 思路: 旋转卡壳 给定点集S,求S的最小覆盖矩形 最小覆盖矩形的四条边上,其中一条边有至少两 ...
- 求取SHP文件的最小外接矩形并裁剪图像
目的: 求取shp文件中每一个形状的最小外接矩形. 根据每一个形状的最小外接矩形裁剪图像. 已知数据: 一个shp文件,包含若干个形状. 2.shp文件对应的影像. 工具 ARCGIS10.4 pyt ...
- opencv findContours()轮廓特征分析大全(求面积、周长、几何矩、质心、凸包、最小外接矩形、最小外接三角形、最小外接椭圆等)
文章目录 前言 一.效果 二.opencv对应函数介绍 1.轮廓面积 2.轮廓周长 3.轮廓几何矩 4.轮廓的最大外接矩形 5.轮廓的凸包 6.轮廓的最小外接矩形 7.轮廓的最小外接三角形 8.轮廓的 ...
- matlab外接矩形,matlab求二值圖像最小外接矩形
全部來自ilovematlab中文論壇,其中matlab較新的版本不再支持其中的有些函數,或者說有些函數的參數做了改變,因此適當修改后貼出來.注:無意侵權,記錄在此自我學習,順帶服務群眾. 首先是尋找 ...
最新文章
- 仔细选择会话状态提供程序
- 给gridview动态生成radiobutton添加OnCheckedChanged监听函数
- 本地连接出来的很慢解决方法
- Centos7 下载、安装、配置、启动部署
- C语言课后习题(58)
- 如何将c语言编译器设置为初始状态,C语言编译器设与实现毕业论文设计.doc
- python输出小数_python输出小数
- 16 个优秀的 Vue 开源项目
- DbgView远程调试
- 安装ghost win7后未能启动服务器,ghost win7系统安装全教程 ghost win7启动失败怎么办...
- 忘记MySQL密码如何重置再到重新设置密码
- Javascript高级程序设计——9.正则表达式(1)
- iOS模块化灰度 A/BTest
- tp6 gatewayWorker
- doctrine 关系
- matlab里vSAS,科学网—【MATLAB】saveas和print保存图片的格式 - 叶瑞杰的博文
- js 根据当前星期做跳转(代码段)
- 计算机无法屏幕亮度,win7电脑屏幕亮度无法调节怎么办?调节屏幕亮度的方法...
- 利用VSPD建立虚拟串口
- Android 信号查看,安卓Android手机怎么快速查看系统信号强度
热门文章
- 阿里巴巴2016校园招聘 研发工程师(二)详解
- 元宇宙NFT最近最火的项目,该如何选择平台呢
- 1058:求一元二次方程
- 用脚本组装xgen 后期文件,缓存正确,毛发飞的可能分析
- 横河DLM2000示波器连接电脑
- html实现鼠标跟随,html5实现鼠标跟随
- 手把手教你用深度学习做物体检测(二):数据标注
- 制造业生产ERP源码,c#制造业通用ERP管理系统源码
- 关于ADS的二次谐波和高次谐波牵引
- mc服务器物品给予,[管理|功能]GiveItem —— 给予物品 | 更好的Give|支持NBT|保存物品[1.12.2|1.16.X]...