凸包を求めるアルゴリズム、最後にjarvisのマーチという方法をやってみます。
考え方としては、まず最初にy座標が一番小さいものを選んで、その点からの角度が一番小さい点を選んでいきます。
角度は内積で求めます。
このアルゴリズムの場合、凸包上の頂点ごとに点の数の繰り返しを行うので、点の数n、頂点数hとすると、計算量はO(hn)になります。
static List<Point> points = new ArrayList<Point>(); static List<Point> hull; static void createConvexHull(){ //Y座標で並べ替え Collections.sort(points, new Comparator() { public int compare(Object o1, Object o2) { return ((Point)o1).y - ((Point)o2).y; } }); //凸包を求める hull = new ArrayList<Point>(); //一番上の点を求める Point first = points.get(0); hull.add(first); int vx = 1; int vy = 0; Point oldpoint = first; for(;;){ //前回の辺との角度が一番小さい点を求める。 Point minpoint = null; int minvecx = 0; int minvecy = 0; double maxcos = -1; for(Point p : points){ if(p == oldpoint) continue; int ox = p.x - oldpoint.x; int oy = p.y - oldpoint.y; //角度を求める double cos = (ox * vx + oy * vy) / (Math.sqrt(ox * ox + oy * oy) * Math.sqrt(vx * vx + vy * vy)); if(cos > maxcos){ //いままでの中で一番角度が小さいとき maxcos = cos; minvecx = ox; minvecy = oy; minpoint = p; } } if(minpoint == first){ //最初の点に戻ったら終わり break; } vx = minvecx; vy = minvecy; oldpoint = minpoint; hull.add(minpoint); } }