您的位置:首页 > 其它

寻找凸包-graham扫描法

2015-10-24 19:22 316 查看
Graham扫描法通过维持一个关于候选点的栈S来解决凸包问题。输入集合Q中的每个点都被压栈一次,非CH(Q)中的点最终被弹出栈。当算法终止时,栈S仅包含CH(Q)中的顶点,以逆时针的顺序出现在边界上。

<span style="font-size:18px;">import java.util.*;
public class Graham
{
static int MAX = 100015;
static POINT[] point = new POINT[MAX];
static int[] stack = new int[MAX];
static int n;
static int top;

static class POINT
{
public double x,y;
public POINT(int x,int y){
this.x = x;
this.y = y;
}
}

//(p1-p0)x(p2-p0),判断两直线的相对位置
static double xmul(POINT p1,POINT p2,POINT p0){
return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);
}

static double distance(POINT p1,POINT p2){
return (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);
}

static void swap(int i,int j){
POINT tmp = point[i];
point[i] = point[j];
point[j] = tmp;
}

static void grahamscan(int n){
//	if(n<2)
int u = 0,i = 0;
for(;i < n;i++)
if((point[i].y < point[u].y)||(point[i].y == point[u].y && point[i].x<point[u].x ))
u = i;
swap(u,0);
Arrays.sort(point,0,n,new MyComp());
for(i=0;i<3;i++) stack[i] = i; //point0 point1 point2入栈
top = 2;
for(i = 3;i < n;i++){
while(xmul(point[i],point[stack[top]],point[stack[top-1]]) >= 0){//弹出非左转的点
if(top == 0) break;
top--;
}
stack[++top] = i;
}
}

static class MyComp implements Comparator<POINT>
{
public int compare(POINT p1,POINT p2){
double xm = xmul(p1,p2,point[0]);
if(xm < 0) return 1;
else if(xm == 0 && distance(p1,point[0])>distance(p2,point[0])) return 1;
else return -1;
}
}

static double area(int n){
double area = 0;
for(int i = 2;i <= n-1;i++){
area += xmul(point[stack[i]],point[stack[i-1]],point[0]);
}
return Math.abs(area)/2;
}

static void input(){
int x=0,y=0;
Scanner cin = new Scanner(System.in);
System.out.println("请输入点数");
n = cin.nextInt();
System.out.println("请输入x,y");
for(int i = 0;i < n;i++){
x = cin.nextInt();
y = cin.nextInt();
point[i] = new POINT(x,y);
}
}

static void print(){
System.out.println("凸包:");
for(int i=0;i<=top;i++){
System.out.print(stack[i]+"-");
}
System.out.println("0");
}
public static void main(String[] args){
input();
grahamscan(n);
System.out.println("area: "+area(n));
print();
}
}
/*
请输入点数
4
请输入x,y
0 0
1 0
0 1
1 1
area: 1.0
0-1-2-3-0
*/</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: