Gift wrapping 算法计算凸包

计算给定集合中的凸包利用Gift wrapping algorithm算法,先找到最左下角的点加入集合,然后比较剩余点到此点的偏转角,找到偏转角最小的加入集合,当偏转角相同时,需要找到最长的一条边的点加入集合,最后即可得到凸包的点集。

public static Set<Point> convexHull(Set<Point> points){
    	
            //throw new RuntimeException("implement me!");
        	ArrayList<Point> ConvexHull=new ArrayList<Point>();
            ArrayList<Point> temppoint=new ArrayList<Point>();
            
            
            temppoint.addAll(points);//将所有点集加入
            Point p0;
            if(temppoint.size()<=3) {
            	return points;
            }//少于三个点直接是凸包
            else {
        		    p0=temppoint.get(0);  //找寻横纵坐标最小的点p0,p0一定是凸包里的点
        		for(Point temp:points) {
        			if(temp.x()<p0.x()) {
        				p0=temp;
        			}
        			else if(temp.x()==p0.x()&&temp.y()<p0.y()) {
        				p0=temp;
        			}
        		}
        		ConvexHull.add(p0);//将p0加入凸包
        		temppoint.remove(p0);
        		
            }
         /*卷包算法:1.以p0为原点,找到极角最小的点,如果角度相同那么选取距离p0远的点。
         该点即为下一个p0,重复(1)中过程,直到回到原点,这个序列就是凸包序列。*/
           int j=0;
            Point p1=p0;
            //Point p2=p0;
            //double minangle=calculateBearingToPoint(0,(int)p0.x(),(int)p0.y(),(int)temppoint.get(0).x(),(int)temppoint.get(0).y());
           //double maxdistance=Math.pow(p0.x() - temppoint.get(0).x(), 2) + Math.pow(p0.y() - temppoint.get(0).y(), 2);//计算距离
            temppoint.add(p0);
            // int n=temppoint.size();
            do {
            	
            	if(j==1) {
            		temppoint.add(p1);
            	}
            	double maxdistance=0;
            	double minangle=360;
            	 
            	Point p2=null;
                 for(Point temp:temppoint) {
            	double tempangle=calculateBearingToPoint(0,(int)p0.x(),(int)p0.y(),(int)temp.x(),(int)temp.y());//计算极角
    			double tempdistance=Math.pow(p0.x() - temp.x(), 2) + Math.pow(p0.y() - temp.y(), 2);//计算距离
                if(tempangle<minangle) {//极角最小
                	minangle=tempangle;
                	p2= temp;
                	maxdistance=tempdistance;
                }
                if(tempangle==minangle&&tempdistance>maxdistance) {//极角相同,选取距离远的点
                	maxdistance=tempdistance;
                	p2= temp;
                }
            	}
            	
            	ConvexHull.add(p2);
            	p0=p2;
            	temppoint.remove(p2);
            	j++;
            	
            }while(ConvexHull.get(j)!=p1);
    		
    		Set<Point> finalresult = new HashSet<Point>();
    		finalresult.addAll(ConvexHull);
    		return finalresult;
    	}
    

测试:

/**
	 * Tests convexHull.
	 */
	@Test
	public void convexHullTest() {
		Set<Point> points = new HashSet<Point>();
		Set<Point> convexHull = new HashSet<Point>();

		assertEquals(convexHull, TurtleSoup.convexHull(points));

		Point p11 = new Point(1, 1);
		Point p1010 = new Point(10, 10);
		Point p110 = new Point(1, 10);
		Point p12 = new Point(1, 2);
		Point p23 = new Point(2, 3);
		Point p32 = new Point(3, 2);

		points.add(p11);
		convexHull.add(p11);
		assertEquals(convexHull, TurtleSoup.convexHull(points));

		points.add(p1010);
		convexHull.add(p1010);
		assertEquals(convexHull, TurtleSoup.convexHull(points));

		points.add(p110);
		convexHull.add(p110);
		assertEquals(convexHull, TurtleSoup.convexHull(points));

		points.add(p12);
		assertEquals(convexHull, TurtleSoup.convexHull(points));

		points.add(p23);
		assertEquals(convexHull, TurtleSoup.convexHull(points));

		points.add(p32);
		convexHull.add(p32);
		assertEquals(convexHull, TurtleSoup.convexHull(points));
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值