计算几何
凸包
n4
通过在不在三角形内部来判断是否为极点,如果为极点那么就是构成凸包的点,如果是在三角形内部的,那就不是构成凸包的点
由于n4会炸,那么in_triangle_test可以分解为三个to_left_test,三个to_left_test如果都为true那么in_triangle_test也为true 通过面积判断是否为true,计算三点形成的面积,若面积为正,则位于直线的左侧,否则位于直线的右侧
bool to_left(Point p,Ponit q,Point s)
{
    int area=p.x*q.y-p.y*q.x+q.x*s.y-q.y*s.x+s.x*p.y-s.y*p.x;
    return area>0;
}
极边法
n3
通过所有点是否都是在一条线的一遍来判断是否是极边,凸包是有所有极边和极边所连接的点组成的
相当于对每一条边判断是否是剩余的每个点都和极边的两点to_left都是一个值,即LEmpty都是false,REmpty都是true 或者说 LEmpty都是true,REmpty都是false
struct Point{
    int x,y;
    int extreme;
}point;
void check_edge(Point S[],int n,int p,int q)
{
    bool LEmpty=true,REmpty=true;
    for(int k=0;k<n&&(LEmpty||REmpty);k++){
        if(k!=p&&k!=p)
            if(to_left(S[p],S[q],S[k])) LEmpty=false;
            else REmpty=false;
    }
    if(LEmpty||REmpty) S[p].extreme=S[q].extreme=true;
}
void markEE(Point S[],int n)
{
    for(int k=0;k<n;k++){
        S[k].extreme=false;
    }
    for(int p=0;p<n;p++){
        for(int q=p+1;q<n;q++){
            check_edge(S,n,p,q);
        }
    }
}
多边形判定法
并不是判断哪些点构成凸包,而是每次加入一个新的点,看他是否会构成新的凸包,构成新的凸包的条件是该点会有两个点与它的关系是LL和RR,则应该把该点插入,否则就不需要
n2 增量法
void in_convex_polygon test
{
    
    
}
Jarvis March
nh
关于第一个点的选择,遵循LTL原则,即lowest_then_leftmost_point,选择出的必定为极点。从极点出发找到一条极边,然后用另一个端点为起始点再找极边。找极边的过程为On两两比较,to_left为true的交换,否则留下。
struct Point{
    int x,y;
    int succ;//后继 
    int extreme;//极点标记 
}point;
int ltl(Point S[],int n)
{
    int LTL=0;
    for(int k=1;k<n;k++){
        if(S[k].y<S[LTL].y||(S[k].y==S[LTL].y&&S[k].x<S[LTL].x)) LTL=k;
    }
    return LTL;
}
void Jarvis(Point S[],int n)
{
    for(int k=0;k<n;k++) S[k].extreme=false;
    int LTL=ltl(s,n);
    int k=LTL;
    do{
        S[k].extreme=true;
        int s=-1;
        for(int t=0;t<n;t++){
            if(t!=k&&t!=s&&(s==-1||!to_left(P[k],P[s],P[t]))) s=t;
        }
        S[k].succ=s;
        k=s;
    }while(LTL!=k)
}
Graham Scan 算法
upper hull && lower hull
 
                     
                    
                