旋转卡壳原理:旋转卡壳详解_大学要有梦想的博客-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;}

旋转卡壳算法求最小外接矩形代码相关推荐

  1. python外包凹多边形生成_Python实现图片查找轮廓、多边形拟合、最小外接矩形代码...

    1.概述 经常用到轮廓查找和多边形拟合等opencv操作,因此记录以备后续使用.本文代码中的阈值条件对图片没有实际意义,仅仅是为了测试. 原图为: 2.测试代码: import cv2 import ...

  2. 【OpenCV】 外接矩形、最小外接矩形、多边形拟合、外接圆

    任务:给定这样一张图片求图片中白色区域的外接矩形.最小外接矩形.拟合多边形以及外接圆 1.外接矩形 x, y, w, h = cv2.boundingRect(points) 输入:点集 返回值:左上 ...

  3. 遍历图像 找最小外接矩形 matlab,2018a版本MatLab利用regionprops函数获取图片中物体轮廓最小外接矩形...

    2018a版本MatLab利用regionprops函数获取图片中物体最小外接矩形 本次内容,用于介绍利用matlab中的regionprops函数来获取图像区域中的物体的最小外接矩形信息(位置(x, ...

  4. python如何做四象图_Python使用四个坐标点来剪切图像目标区域的最小外接矩形,python,利用,对,图片,进行,裁剪...

    在图像裁剪操作中,opencv和pillow两个库都具有相应的函数,但是这两个库中的函数仅仅能对与图片平行的矩形进行裁剪操作,如果想要对目标的最小外接矩形进行裁剪该如何操作呢?如下所示: 具体处理该问 ...

  5. CGAL求最小外包矩形

    有两种所谓的最小外包矩形,第一种通过求所有节点的最小与最大xy来求的,这种叫与坐标轴平行的最小外包矩形:另外一种则是本文说的这种,与范围的形状与走势有关的,叫非坐标轴平行的最小外包矩形,效果如下图所示 ...

  6. UVA10173(求凸包的面积最小外接矩形)

    题目:10173 - Smallest Bounding Rectangle 求凸包的最小外接矩形的面积. 思路: 旋转卡壳 给定点集S,求S的最小覆盖矩形 最小覆盖矩形的四条边上,其中一条边有至少两 ...

  7. 求取SHP文件的最小外接矩形并裁剪图像

    目的: 求取shp文件中每一个形状的最小外接矩形. 根据每一个形状的最小外接矩形裁剪图像. 已知数据: 一个shp文件,包含若干个形状. 2.shp文件对应的影像. 工具 ARCGIS10.4 pyt ...

  8. opencv findContours()轮廓特征分析大全(求面积、周长、几何矩、质心、凸包、最小外接矩形、最小外接三角形、最小外接椭圆等)

    文章目录 前言 一.效果 二.opencv对应函数介绍 1.轮廓面积 2.轮廓周长 3.轮廓几何矩 4.轮廓的最大外接矩形 5.轮廓的凸包 6.轮廓的最小外接矩形 7.轮廓的最小外接三角形 8.轮廓的 ...

  9. matlab外接矩形,matlab求二值圖像最小外接矩形

    全部來自ilovematlab中文論壇,其中matlab較新的版本不再支持其中的有些函數,或者說有些函數的參數做了改變,因此適當修改后貼出來.注:無意侵權,記錄在此自我學習,順帶服務群眾. 首先是尋找 ...

最新文章

  1. 仔细选择会话状态提供程序
  2. 给gridview动态生成radiobutton添加OnCheckedChanged监听函数
  3. 本地连接出来的很慢解决方法
  4. Centos7 下载、安装、配置、启动部署
  5. C语言课后习题(58)
  6. 如何将c语言编译器设置为初始状态,C语言编译器设与实现毕业论文设计.doc
  7. python输出小数_python输出小数
  8. 16 个优秀的 Vue 开源项目
  9. DbgView远程调试
  10. 安装ghost win7后未能启动服务器,ghost win7系统安装全教程 ghost win7启动失败怎么办...
  11. 忘记MySQL密码如何重置再到重新设置密码
  12. Javascript高级程序设计——9.正则表达式(1)
  13. iOS模块化灰度 A/BTest
  14. tp6 gatewayWorker
  15. doctrine 关系
  16. matlab里vSAS,科学网—【MATLAB】saveas和print保存图片的格式 - 叶瑞杰的博文
  17. js 根据当前星期做跳转(代码段)
  18. 计算机无法屏幕亮度,win7电脑屏幕亮度无法调节怎么办?调节屏幕亮度的方法...
  19. 利用VSPD建立虚拟串口
  20. Android 信号查看,安卓Android手机怎么快速查看系统信号强度

热门文章

  1. 阿里巴巴2016校园招聘 研发工程师(二)详解
  2. 元宇宙NFT最近最火的项目,该如何选择平台呢
  3. 1058:求一元二次方程
  4. 用脚本组装xgen 后期文件,缓存正确,毛发飞的可能分析
  5. 横河DLM2000示波器连接电脑
  6. html实现鼠标跟随,html5实现鼠标跟随
  7. 手把手教你用深度学习做物体检测(二):数据标注
  8. 制造业生产ERP源码,c#制造业通用ERP管理系统源码
  9. 关于ADS的二次谐波和高次谐波牵引
  10. mc服务器物品给予,[管理|功能]GiveItem —— 给予物品 | 更好的Give|支持NBT|保存物品[1.12.2|1.16.X]...