//Graham扫描法
#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
struct node{
double x,y;
}p[maxn],P[maxn];//p全集,P凸点
int n,tot;//n点数,tot凸点数
double X(node A,node B,node C){
return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y); //叉积 (相似三角形)
}
double len(node A,node B){
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
bool cmp(node A,node B){ //排序
double pp=X(p[0],A,B);
if(pp>0)return true;
if(pp<0)return false;
return len(p[0],A)<len(p[0],B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(n==1){
}
else if(n==2){
}
else {
for(int i=0;i<n;i++){ //确定初始点
if(p[i].y<p[0].y){
swap(p[i],p[0]);
}
else if(p[i].y==p[0].y && p[i].x<p[0].x){
swap(p[i],p[0]);
}
}
sort(p+1,p+n,cmp);
P[0]=p[0];
P[1]=p[1];
tot=1;
for(int i=2;i<n;i++){
while(tot>0 && X(P[tot-1],P[tot],p[i])<=0)//回溯
tot--;
tot++;
P[tot]=p[i];
}
//P中为所有凸点
}
return 0;
}
判断一个点 p3 是在直线 p1p2 的左边还是右边(坐标:p1(x1,y1),p2(x2,y2),p3(x3,y3))
当上式结果为正时,p3在直线 p1p2 的左侧;当结果为负时,p3在直线 p1p2 的右边。
http://blog.csdn.net/bone_ace/article/details/46239187
这篇博客介绍了凸包问题的常用解法