160 lines
5.2 KiB
Java
160 lines
5.2 KiB
Java
|
/*This is a Java Program to implement Quick Hull Algorithm to find convex hull. Here we’ll talk about the Quick Hull algorithm, which is one of the easiest to implement and has a reasonable expected running time of O(n log n).*/
|
|||
|
|
|||
|
import java.util.ArrayList;
|
|||
|
import java.util.Scanner;
|
|||
|
|
|||
|
public class QuickHull
|
|||
|
{
|
|||
|
public ArrayList<Point> quickHull(ArrayList<Point> points)
|
|||
|
{
|
|||
|
ArrayList<Point> convexHull = new ArrayList<Point>();
|
|||
|
if (points.size() < 3)
|
|||
|
return (ArrayList) points.clone();
|
|||
|
int minPoint = -1, maxPoint = -1;
|
|||
|
int minX = Integer.MAX_VALUE;
|
|||
|
int maxX = Integer.MIN_VALUE;
|
|||
|
for (int i = 0; i < points.size(); i++)
|
|||
|
{
|
|||
|
if (points.get(i).x < minX)
|
|||
|
{
|
|||
|
minX = points.get(i).x;
|
|||
|
minPoint = i;
|
|||
|
}
|
|||
|
if (points.get(i).x > maxX)
|
|||
|
{
|
|||
|
maxX = points.get(i).x;
|
|||
|
maxPoint = i;
|
|||
|
}
|
|||
|
}
|
|||
|
Point A = points.get(minPoint);
|
|||
|
Point B = points.get(maxPoint);
|
|||
|
convexHull.add(A);
|
|||
|
convexHull.add(B);
|
|||
|
points.remove(A);
|
|||
|
points.remove(B);
|
|||
|
ArrayList<Point> leftSet = new ArrayList<Point>();
|
|||
|
ArrayList<Point> rightSet = new ArrayList<Point>();
|
|||
|
for (int i = 0; i < points.size(); i++)
|
|||
|
{
|
|||
|
Point p = points.get(i);
|
|||
|
if (pointLocation(A, B, p) == -1)
|
|||
|
leftSet.add(p);
|
|||
|
else if (pointLocation(A, B, p) == 1)
|
|||
|
rightSet.add(p);
|
|||
|
}
|
|||
|
hullSet(A, B, rightSet, convexHull);
|
|||
|
hullSet(B, A, leftSet, convexHull);
|
|||
|
return convexHull;
|
|||
|
}
|
|||
|
|
|||
|
public int distance(Point A, Point B, Point C)
|
|||
|
{
|
|||
|
int ABx = B.x - A.x;
|
|||
|
int ABy = B.y - A.y;
|
|||
|
int num = ABx * (A.y - C.y) - ABy * (A.x - C.x);
|
|||
|
if (num < 0)
|
|||
|
num = -num;
|
|||
|
return num;
|
|||
|
}
|
|||
|
|
|||
|
public void hullSet(Point A, Point B, ArrayList<Point> set,
|
|||
|
ArrayList<Point> hull)
|
|||
|
{
|
|||
|
int insertPosition = hull.indexOf(B);
|
|||
|
if (set.size() == 0)
|
|||
|
return;
|
|||
|
if (set.size() == 1)
|
|||
|
{
|
|||
|
Point p = set.get(0);
|
|||
|
set.remove(p);
|
|||
|
hull.add(insertPosition, p);
|
|||
|
return;
|
|||
|
}
|
|||
|
int dist = Integer.MIN_VALUE;
|
|||
|
int furthestPoint = -1;
|
|||
|
for (int i = 0; i < set.size(); i++)
|
|||
|
{
|
|||
|
Point p = set.get(i);
|
|||
|
int distance = distance(A, B, p);
|
|||
|
if (distance > dist)
|
|||
|
{
|
|||
|
dist = distance;
|
|||
|
furthestPoint = i;
|
|||
|
}
|
|||
|
}
|
|||
|
Point P = set.get(furthestPoint);
|
|||
|
set.remove(furthestPoint);
|
|||
|
hull.add(insertPosition, P);
|
|||
|
// Determine who's to the left of AP
|
|||
|
ArrayList<Point> leftSetAP = new ArrayList<Point>();
|
|||
|
for (int i = 0; i < set.size(); i++)
|
|||
|
{
|
|||
|
Point M = set.get(i);
|
|||
|
if (pointLocation(A, P, M) == 1)
|
|||
|
{
|
|||
|
leftSetAP.add(M);
|
|||
|
}
|
|||
|
}
|
|||
|
// Determine who's to the left of PB
|
|||
|
ArrayList<Point> leftSetPB = new ArrayList<Point>();
|
|||
|
for (int i = 0; i < set.size(); i++)
|
|||
|
{
|
|||
|
Point M = set.get(i);
|
|||
|
if (pointLocation(P, B, M) == 1)
|
|||
|
{
|
|||
|
leftSetPB.add(M);
|
|||
|
}
|
|||
|
}
|
|||
|
hullSet(A, P, leftSetAP, hull);
|
|||
|
hullSet(P, B, leftSetPB, hull);
|
|||
|
}
|
|||
|
|
|||
|
public int pointLocation(Point A, Point B, Point P)
|
|||
|
{
|
|||
|
int cp1 = (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x);
|
|||
|
if (cp1 > 0)
|
|||
|
return 1;
|
|||
|
else if (cp1 == 0)
|
|||
|
return 0;
|
|||
|
else
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
public static void main(String args[])
|
|||
|
{
|
|||
|
System.out.println("Quick Hull Test");
|
|||
|
Scanner sc = new Scanner(System.in);
|
|||
|
System.out.println("Enter the number of points");
|
|||
|
int N = sc.nextInt();
|
|||
|
ArrayList<Point> points = new ArrayList<Point>();
|
|||
|
System.out.println("Enter the coordinates of each points: <x> <y>");
|
|||
|
for (int i = 0; i < N; i++)
|
|||
|
{
|
|||
|
int x = sc.nextInt();
|
|||
|
int y = sc.nextInt();
|
|||
|
Point e = new Point(x, y);
|
|||
|
points.add(i, e);
|
|||
|
}
|
|||
|
QuickHull qh = new QuickHull();
|
|||
|
ArrayList<Point> p = qh.quickHull(points);
|
|||
|
System.out
|
|||
|
.println("The points in the Convex hull using Quick Hull are: ");
|
|||
|
for (int i = 0; i < p.size(); i++)
|
|||
|
System.out.println("(" + p.get(i).x + ", " + p.get(i).y + ")");
|
|||
|
sc.close();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
Quick Hull Test
|
|||
|
Enter the number of points
|
|||
|
4
|
|||
|
Enter the coordinates of each points: <x> <y>
|
|||
|
12 32
|
|||
|
45 98
|
|||
|
65 12
|
|||
|
10 30
|
|||
|
The points in the Convex hull using Quick Hull are:
|
|||
|
(10, 30)
|
|||
|
(45, 98)
|
|||
|
(65, 12)
|