算法学习 寻找最大凸多边形

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int find(int va,int num,float *lcos);
int check(float cos1,float cos2);
float ad_cos(int x,int y);
typedef struct POINT{
	int x;
	int y;
	int flag;
}Point;
Point a[65535];
int main(void)
{

	int i,num,start,j,ret;
	int result[65535]={0};
	scanf("%d",&num);
	start = 0;
	for(i=0;i<num;i++){
		getchar();//ignore ';'
		scanf("%d,%d",&(a[i].x),&(a[i].y));
		a[i].flag=0;
		if(a[i].y>a[start].y||((a[i].y==a[start].y)&&(a[i].x<a[start].x)))//use the top point as the start point
			start = i;
	}
	result[0]=start;
	i = 1;
	ret = start;
	float lcos = -2;//first last angel not exist so use -2
	while(1){
		ret=find(ret,num,&lcos);
		if(ret==start)
			break;
		result[i++]=ret;
	}
	for(j=0;j<i-2;j++)
		printf("%d,%d;",a[result[j]].x,a[result[j]].y);
	printf("%d,%d",a[result[i-1]].x,a[result[i-1]].y);
	return 0;
}

int find(int va,int num,float *lcos)
{
	int i,x,y,min,xmin;
	float cosi,mcos;//lcos record last round cos,mcos record this round min cos
	min = -1;
	for(i=0;i<num;i++){
		if(a[i].flag==1||i==va)
			continue;
		x=a[i].x-a[va].x;
		y=a[i].y-a[va].y;
		cosi = ad_cos(x,y);
		if(x==y&&x==0)
			return -1;//error input value
		if(min==-1){//get first effective point
			if(check(cosi,*lcos)!=1)//new angle must be bigger than the last round.
				continue;
			xmin = x;
			min = i;
			mcos = cosi;
		}
		else{
			if(check(cosi,mcos)==0&&check(cosi,*lcos)==1){//find the min angle point also,the min angle is bigger than the last round.
				xmin = x;
				min = i;
				mcos = cosi;
			}
		}
	}
	for(i=0;i<num;i++){//remove point on line of this round
		if(a[i].flag==1||i==va)
			continue;
		x=a[i].x-a[va].x;
		y=a[i].y-a[va].y;
		cosi = ad_cos(x,y);
		if(check(cosi,mcos)==3)
		{
			if(abs(x)>abs(xmin)){
				a[min].flag = 1;
				min = i;
			}
			else
				a[i].flag=1;		
		}
	}
	a[min].flag = 1;
	*lcos = mcos;
	return min;
}
//this func adjust the cos,and finally,the bigger cos,the bigger angle.:
float ad_cos(int x,int y){
	float cos1 = 0;
	cos1 = x*x*1.0/(x*x+y*y);
	if(x<0)
		cos1 = cos1*(-1);
	if(y<=0)
		cos1 = (-1)*cos1;
	else
		cos1 = cos1+2;
	return cos1;
}

int check(float cos1,float cos2)
{
	if(cos1<cos2)
		return 0;
	else if(cos1>cos2)
		return 1;
	else
		return 3;
}

  

posted on 2015-09-14 11:00  hanahimi  阅读(381)  评论(0)    收藏  举报

导航