凸包问题
点集Q的凸包是指一个最小凸多边形,Q中的点或者在这个最小凸多边形边上或者在其内部。二维平面上的凸包问题就是对于一组平面上的点,求一个包含所有点的最小的凸多边形。
解决二维凸包问题的方法有很多,主要有分治法,Graham扫描法,Jarvis步进法等。
其中Jarvis步进法是通过夹角来进行点的寻找与加入,可以先将最靠左下方的点作为初始点,之后以该点为起点,y轴正方向为轴,逐个加入逆时针方向角度最小的一个点以及连成的边加入集合中,并作为下一次寻找的起点来进行循环的操作,直到最后回到最左下处的初始点,此时集合内元素即为二维凸包问题的解。
一个实现:
public static int triplet(Point p,Point q,Point r) {
double val = (((int)q.y()-(int)p.y())*((int)r.x()-(int)q.x()))-(((int)q.x()-
(int)p.x())*((int)r.y()-(int)q.y()));
if(val == 0) {
return 0;
}
return (val > 0)? 1 : 2;
}
public static Set<Point> convexHull(Set<Point> points) {
if (points.size()<3) {
return points;
}
Set<Point> hull = new HashSet<Point>();
List<Point> list = new ArrayList(points);
int n=points.size();
int l=0,q;
for(int i=1; i<n; i++) {
if((int)list.get(i).x()<(int)list.get(l).x())
{
l = i;
}
}
int p=l;
do
{
hull.add(list.get(p));
q = (p+1)%(n-1);
for(int i=0; i<n; i++)
{
if(triplet(list.get(p),list.get(i),list.get(q)) == 2)
{
q = i;
}
}
p = q;
}while(p!=l);
return hull;
}
凸包问题描述:https://baike.baidu.com/item/%E5%87%B8%E5%8C%85/179150?fr=aladdin
参考:https://blog.csdn.net/u011001084/article/details/72768075
https://blog.csdn.net/zbspy_zjf/article/details/78822132