凸包算法与JAVA求解的基本思路
一、凸包
凸包(Convex Hull)是一个计算几何(图形学)中的概念。
在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,...Xn)的凸组合来构造。
简单来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它的内部包含了点集中其余所有的点。
二、凸包算法的基本思路
如下图所示:
①首先我们要从最左、最下的点开始,如图中的B点(‘左’的优先级高,假设点B的正下方有一点Z,则从Z点开始);
②设一个向量以B点作为根部,方向朝正上方‘↑’;
③令向量绕根部顺时针旋转,直到找到第一个在向量所指向的点(如图中点G,点F是第二个向量所能指向的点),若向量方向上有多个点,则选取距离最远的点;
④令该点成为向量新的起点,方向不变(该步中方向为向量的方向);
⑤重复③、④步,直到③中所找的点为初始点(图中的B点);
⑥整个过程中找到的所有的点构成了凸包的点集,相邻的找到的点之间的连线构成了凸包多边形,该图中找到的点的顺序为B - G - D - K - H - J - B。
三、JAVA求解凸包的一些准备工作
在最终求解凸包算法之前,我们需要准备一些辅助计算的方法:
(1)calculateRegularPolygonAngle(int sides)
①作用:输入多边形边数sides,返回多边形的内角度数总和;
②代码实现:
public static double calculateRegularPolygonAngle(int sides) {//如果多边形边数小于3,则不是多边形,返回0if(sides<3)return 0;//否则,代入公式计算内角和double angle=(double)(sides-2)*180/sides;return angle;}
(2)calculateBearingToPoint(double currentBearing, int currentX, int currentY, int targetX, int targetY)
①作用:输入目标点、向量根部点的坐标,以及向量方向与Y轴正方向的夹角,返回向量想要指向目标点所要转过的正角(正角:顺时针所要扫过的角度);
②代码实现:
public static double calculateBearingToPoint(double currentBearing, int currentX, int currentY,int targetX, int targetY) {//计算从根部点到目标点的向量的横坐标double x=(double)(targetX-currentX);//同上,计算向量的纵坐标double y=(double)(targetY-currentY);//调用Math类下的atan2方法,计算向量所要偏转的正角度double degree=90-currentBearing-Math.toDegrees(Math.atan2(y, x));//如果角度为负,则转为正角if(degree<0) degree+=360;return degree;}
四、JAVA求解凸包的主函数
Set<Point> convexHull(Set<Point> points)
①作用:输入所有点构成的点集,返回凸包多边形的点集;
②代码实现:
public static Set<Point> convexHull(Set<Point> points) {//判断点的总数是否小于3,小于3则不能构成多边形if(points.size() < 3) {return points;}//定义新的Set集合,其中不会有重复元素,符合我们的要求Set<Point> set = new HashSet<>();Point xmin = new Point(Double.MAX_VALUE, Double.MAX_VALUE);//运用for-each遍历的方式,在所有点中寻找最左的点for(Point item : points) {if (item.x() < xmin.x() || (item.x() == xmin.x() && item.y() < xmin.y()))xmin = item;}//设最左的点为初始起点Point nowPoint = xmin, tempPoint = xmin;//初始化指向角度为0double nowAngle = 0, minAngle = 360, tempAngle = 0;double distance;double maxdistance = 0;//无差别地遍历所有的点do{set.add(tempPoint);// 遍历全部点,寻找下一个在凸包上的点for(Point item : points) {//当某一点不在点集之中或者该点为起始点if ((!set.contains(item) || item == xmin) ) {//调用判断calculateBearingToPoint方法计算所需要偏转的角度tempAngle = calculateBearingToPoint(nowAngle, (int)nowPoint.x(), (int)nowPoint.y(), (int)item.x(), (int)item.y());//计算目标点与所在点之间的距离distance = (item.x() - nowPoint.x())*(item.x() - nowPoint.x()) + (item.y() - nowPoint.y())*(item.y() - nowPoint.y());/*如果某一点的偏转角比之前所找到的最小角度还要小则该角度成为了最小偏转角多个点在同一方向上时取距离所在点最远的目标点*/if(tempAngle < minAngle || ((tempAngle == minAngle) && (distance > maxdistance))) {minAngle = tempAngle;tempPoint = item;maxdistance = distance;}}}//遍历完所有点后,初始化判断指标,从刚刚找到的目标点再次出发,重复上述步骤nowAngle = minAngle;minAngle = 360;nowPoint = tempPoint;} while(nowPoint != xmin); // 当下一个点为第一个点时找到了凸包上的全部点,退出循环return set;}
最终返回的Set类型的集合就是我们所要求得的凸包多边形点集。
五、实现过程中需要的Math类中的方法
(1)Math.round
①方法原型:long Math.round(double a)
②作用:输入一个浮点型小数,返回四舍五入后的值
(2)Math.toDegrees
①方法原型:double Math.toDegrees(double radian)
②作用:输入一个弧度制,返回对应的角度值
(3)Math.atan2(y,x)
①方法原型:double Math.atan2(double y,double x) (注意:输入的坐标值中纵坐标y在前面)
②作用:输入一个以原点为起点的向量所指向的一个点的坐标(x,y),返回该向量与X轴所夹正角的弧度值arctan(y/x)
凸包算法与JAVA求解的基本思路相关推荐
- java快排算法解读,java 快排的思路与算法
java 快排的思路与算法 有时候面试的时候的会问道Arrays.sort()是怎么实现的,我以前根本不知道是什么东西,最近点进去看了一下.直接吓傻, //看到这个时候还是比较淡定的,可怕的事情来了. ...
- java 凸包算法_Melkman凸包算法的Java实现
public class Point{ private float x; //X坐标 private float y; //Y坐标 private double arCos;//与P0点的角度 pub ...
- java 地理围栏实现_使用Path2D和凸包算法实现地理围栏服务
前言 地理围栏(Geo-fencing)是LBS的一种新应用,就是用一个虚拟的栅栏围出一个虚拟地理边界.在物流配送行业应用比较广,划分每个配送网点或者商家配送的范围,提高配送员的配送效率和服务的范围. ...
- java实现回溯算法,java基础面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- 数据结构与算法【Java】05---排序算法总结
前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...
- 数据结构和算法——用动态规划求解最短路径问题
一.动态规划求解问题的思路 在<算法导论>上,动态规划的求解过程主要分为如下的四步: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值 由计算出的结果构造一个最 ...
- 算法(Java)——动态规划
算法相关数据结构总结: 序号 数据结构 文章 1 动态规划 动态规划之背包问题--01背包 动态规划之背包问题--完全背包 动态规划之打家劫舍系列问题 动态规划之股票买卖系列问题 动态规划之子序列问题 ...
- 八大排序算法(java实现) 冒泡排序 快速排序 堆排序 归并排序 等
八大排序算法 一.直接插入 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 二.希尔排序 - 1.基本思路 - 2.代码实现 - 3.时间复杂度和空间复杂度 三.简单选择 - 1. ...
- 蚁群优化算法的JAVA实现
蚁群算法简介 蚁群算法是群智能算法的一种,所谓的群智能是一种由无智能或简单智能的个体通过任何形式的聚集协同而表现出智能行为,它为在没有集中控制且不提供全局模型的前提下寻找复杂的分布式问题求解方案提供了 ...
- 树冠体积计算之台体-凸包算法
既然都已经复现了体元累加法,就顺带着也复现一下台体-凸包算法哈哈. 文章目录 一.简介 二.实现步骤 三.代码实现 四.小结 一.简介 该方法的思路也是很简单,就是将树冠分割为多个不规则的台体,对每个 ...
最新文章
- GIS软件开发工具包TatukGIS Developer Kernel 发布 v11.3.0-Unstable1丨附下载
- python0.1+0.2_为什么0.1+0.2=0.30000000000000004
- 第二十六讲 有特殊特征值的微分方程组
- delphi与api中的加一减一函数
- 全排列—leetcode46
- PAT——1074. 宇宙无敌加法器(20)
- spring 13-Spring框架基于Annotation的AOP配置
- JavaScript高级程序设计(4)
- 【音乐拼接】WAV格式
- python如何批量导出数据_【Python】批量导出数据并处理——第一弹
- 红帽linux安装网卡,redhat网卡驱动程序安装步骤
- 注意JDBC数据库连接中资源关闭的顺序
- 软件工程师应该如何吵架?
- python中气泡图文字标签_Excel中制作气泡图及为气泡图的系列数据点添加文本数据标签...
- 百度地图转换腾讯地图 php,用PHP实现腾讯地图和百度地图的相互转换范例
- 古人的名与字、号、讳、谥有什么区别
- 增量式PID控制算法及仿真
- opencv 轮廓放大_【走进OpenCV】这样腐蚀下来让我膨胀!
- 改造智能风扇之——普通BLDC风扇拆机分析篇
- SQL数据查询——嵌套查询
热门文章
- 在线答题java背景_答题功能java
- 科学计算与可视化python_Python科学计算和可视化
- C/C++取数据中高8位,低8位,合成新数据
- 密码库LibTomCrypt学习记录——(2.2)分组密码算法的工作模式——ECB模式
- 地图标识符号大全_资源小结:中国分省地图大全(10.23版)
- 最新30套Java项目实战
- 手机抓直播源工具app_香港卫视 手机在线直播 央视源
- Java JDK下载安装及环境配置超详细图文教程
- JavaScript高级教程——(19)构造函数、原型、原型链、继承
- 最详细的JavaScript教程(高级篇),深入学习JavaScript