计算几何小家桶

只到旋转卡壳部分

参考://https://www.cnblogs.com/Xing-Ling/p/12102489.html

#include<bits/stdc++.h>
#define ldb long double
using namespace std;
const ldb PI = acos(-1.0);
const ldb INF = 1e100;
const ldb eps = 1e-10;

int read(){
    int s=0,w=1; char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))s=s*10+(ch^48),ch=getchar();
    return s*w;
}
int sign(ldb a){return fabs(a)<eps?0:(a>0?1:-1);}

struct Vector{
    ldb x,y;
    Vector(ldb x=0,ldb y=0):x(x),y(y){}
    void scan(){scanf("%Lf%Lf",&x,&y);}
    void print(){printf("%.2Lf %.2Lf\n",x,y);}
    ldb theta(){return atan2(y,x);}
};
Vector operator+(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator-(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator*(Vector a,ldb b){return Vector(a.x*b,a.y*b);}
bool operator==(Vector a,Vector b){return !sign(a.x-b.x)&&!sign(a.y-b.y);}
bool operator<(Vector a,Vector b){return sign(a.x-b.x)==0?sign(a.y-b.y)<0:sign(a.x-b.x)<0;}
ldb Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
ldb Cro(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
ldb Dot(Vector o,Vector a,Vector b){return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y);}
ldb Cro(Vector o,Vector a,Vector b){return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);}
ldb Dis(Vector a,Vector b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
ldb Dis2(Vector a,Vector b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
ldb Len(Vector a){return sqrt(Dot(a,a));}
Vector Rotate(Vector a,ldb alpha){
    ldb x=a.x*cos(alpha)+a.y*sin(alpha);
    ldb y=-a.x*sin(alpha)+a.y*cos(alpha);
    return Vector(x,y);
}
Vector Rotate(Vector a,Vector b,ldb alpha){
    ldb x=(a.x-b.x)*cos(alpha)+(a.y-b.y)*sin(alpha);
    ldb y=(b.x-a.x)*sin(alpha)+(a.y-b.y)*cos(alpha);
    return Vector(x,y);
}
bool p_at_line(Vector p,Vector a,Vector b){
    return !sign(Cro(p-a,b-a));
}
bool p_at_seg(Vector p,Vector a,Vector b){
    return !sign(Cro(p-a,b-a))&&sign(Dot(p-a,p-b))<=0;
}
Vector p_to_line_foot(Vector p,Vector a,Vector b){
    Vector x=p-a,y=p-b,z=b-a;
    ldb len1=Dot(x,z)/Len(z),len2=-1.0*Dot(y,z)/Len(z);
    return a+z*(len1/(len1+len2));
}
ldb p_to_line(Vector p,Vector a,Vector b){
    if(a==b)return Dis(a,p);
    Vector x=p-a,z=b-a;
    return fabs(Cro(x,z)/Len(z));
}
ldb p_to_seg(Vector p,Vector a,Vector b){
    if(a==b)return Dis(a,p);
    Vector x=p-a,y=p-b,z=b-a;
    if(sign(Dot(x,z))<0)return Len(x);
    if(sign(Dot(y,z))>0)return Len(y);
    return fabs(Cro(x,z)/Len(z));
}
Vector p_to_seg_foot(Vector p,Vector a,Vector b){
    if(a==b)return a;
    Vector x=p-a,y=p-b,z=b-a;
    if(sign(Dot(x,z))<0)return a;
    if(sign(Dot(y,z))>0)return b;
    return p_to_line_foot(p,a,b);
}
Vector get_cross_ll(Vector a,Vector b,Vector c,Vector d){
    Vector x=b-a,y=d-c,z=a-c;
    return a+x*(Cro(y,z)/Cro(x,y));
}
bool cross_ls(Vector a,Vector b,Vector c,Vector d){
    return p_at_seg(get_cross_ll(a,b,c,d),c,d);
}
int cross_ss(Vector a,Vector b,Vector c,Vector d){
    if(!(sign(max(a.x,b.x)-min(c.x,d.x))!=-1&&sign(max(c.x,d.x)-min(a.x,b.x))!=-1
       &&sign(max(a.y,b.y)-min(c.y,d.y))!=-1&&sign(max(c.y,d.y)-min(a.y,b.y))!=-1))return 0;//涓嶄氦
    ldb x1=Cro(b-a,c-a),x2=Cro(b-a,d-a);
    ldb y1=Cro(d-c,a-c),y2=Cro(d-c,b-c);
    if(sign(x1)*sign(x2)==0&&sign(y1)*sign(y2)==0)return 2;//閲嶅悎
    return sign(x1)*sign(x2)<=0&&sign(y1)*sign(y2)<=0;
}
Vector get_cross_ss(Vector a,Vector b,Vector c,Vector d){
    int op=cross_ss(a,b,c,d);
    if(op==0)return Vector(INF,op);
    if(op==2){
        if(a==c||a==d)return a;
        if(b==c||b==d)return b;
        return Vector(INF,op);
    }
    Vector x=b-a,y=d-c,z=a-c;
    return a+x*(Cro(y,z)/Cro(x,y));
}
bool s_at_sleft(Vector o,Vector a,Vector b){//oa 鍦?ob 宸﹁竟锛堜笉鍚噸鍙狅級
    return sign(Cro(a-o,b-o))<0;
}
bool s_at_sright(Vector o,Vector a,Vector b){
    return sign(Cro(a-o,b-o))>0;
}
bool p_in_tri(Vector p,Vector a,Vector b,Vector c){
    if(s_at_sleft(a,b,c))swap(b,c);
    if(s_at_sleft(a,b,p))return false;
    if(s_at_sleft(b,c,p))return false;
    if(s_at_sleft(c,a,p))return false;
    return true;
}
int p_in_poly(Vector *p,int n,Vector a){
    int cnt=0; ldb tmp;
    for(int i=1;i<=n;++i){
        int j=i<n?i+1:1;
        if(p_at_seg(a,p[i],p[j]))return 2;//杈逛笂
        if(a.y>=min(p[i].y,p[j].y)&&a.y<max(p[i].y,p[j].y))
            tmp=p[i].x+(a.y-p[i].y)/(p[j].y-p[i].y)*(p[j].x-p[i].x),cnt+=sign(tmp-a.x)>0;
    }
    return cnt&1;//1 鍐呴儴 0 澶栭儴
}
bool seg_in_poly(Vector *p,int n,Vector a,Vector b){
    if(!p_in_poly(p,n,a)||!p_in_poly(p,n,b))return false;
    p[0]=p[n],p[n+1]=p[1];
    static Vector stk[100005]; int top=0;
    stk[++top]=a,stk[++top]=b;
    for(int i=1;i<=n;++i)if(cross_ss(a,b,p[i],p[i-1])){
        if(p_at_seg(p[i],a,b)){stk[++top]=p[i];continue;}
        if(p_at_seg(p[i-1],a,b)||p_at_seg(a,p[i-1],p[i])||p_at_seg(b,p[i-1],p[i]))continue;
        return false;
    }
    sort(stk+1,stk+1+top);
    for(int i=2;i<=top;++i)
        if(!p_in_poly(p,n,Vector((stk[i-1].x+stk[i].x)/2,(stk[i-1].y+stk[i].y)/2)))return false;
    return true;
}
bool poly_out_poly(Vector *a,int n,Vector *b,int m){
    for(int i=1;i<=n;++i){
        int j=i<n?i+1:1;
        for(int i2=1;i2<=m;++i2){
            int j2=i2<m?i2+1:1;
            if(cross_ss(a[i],a[j],b[i2],b[j2]))return false;
            if(p_in_poly(b,m,a[i])||p_in_poly(a,n,b[i2]))return false;
        }
    }
    return true;
}
ldb polyarea(Vector *p,int n){
    ldb s=0;
    for(int i=1;i<=n;++i)
        s+=Cro(p[i],p[i<n?i+1:1]);
    return s/2.0;
}
// pair<int,int> Graham(Vector *p,int n,Vector *cv){
//     sort(p+1,p+1+n);
//     int top=0;
//     for(int i=1;i<=n;++i){//涓嬪嚫澹?
//         while(top>1&&sign(Cro(cv[top]-cv[top-1],p[i]-cv[top-1]))<=0)--top;
//         cv[++top]=p[i];
//     }
//     int tmp=top;
//     for(int i=n;i>=1;--i){//涓婂嚫澹?
//         while(top>tmp&&sign(Cro(cv[top]-cv[top-1],p[i]-cv[top-1]))<=0)--top;
//         cv[++top]=p[i];
//     }
//     return pair<int,int>(tmp,top-1);//1..tmp 涓嬪嚫,tmp+1..top-1 涓婂嚫    
// }
Vector mn(INF,INF);
bool cmp(Vector a,Vector b){
    ldb alpha=atan2(a.y-mn.y,a.x-mn.x),beta=atan2(b.y-mn.y,b.x-mn.x);
    if(sign(alpha-beta)==0)return a.x<b.x;
    else return alpha<beta;
}
int Graham(Vector *p,int n,Vector *cv){
    int id,top=0;
    for(int i=1;i<=n;++i)
        if(mn.y>p[i].y||mn.y==p[i].y&&mn.x>p[i].x)mn=p[i],id=i;
    swap(p[id],p[1]),sort(p+2,p+1+n,cmp);
    cv[++top]=p[1];
    for(int i=2;i<=n;++i){
        while(top>1&&sign(Cro(cv[top]-cv[top-1],p[i]-cv[top-1]))<=0)--top;
        cv[++top]=p[i];
    }
    return top;
}
int get_diameter_of_convex(Vector*p,int n){
    int ans=0,j=3;
    if(n==2)return Dis2(p[1],p[2]);
    p[++n]=p[1];
    for(int i=1;i<n;++i){
        while(sign(Cro(p[j]-p[i],p[j]-p[i+1])-Cro(p[j+1]-p[i],p[j+1]-p[i+1]))<0)
            j=(j+1)%n+1;
        ans=max(ans,(int)max(Dis2(p[j],p[i]),Dis2(p[j],p[i+1])));
    }
    return ans;
}

Vector p[1000000],cv[1000000];
int n,l;

signed main(){
    n=read(),l=read();
    for(int i=1;i<=n;++i)p[i].scan();
    int len=Graham(p,n,cv);
    ldb ans=0;
    for(int i=2;i<=len;++i)
        ans+=Dis(cv[i],cv[i-1]);
    ans+=Dis(cv[1],cv[len]);
    printf("%d",(int)(ans+2*PI*l+0.5));
    return 0;
}
posted @ 2022-01-27 17:17  _Famiglistimo  阅读(30)  评论(1编辑  收藏  举报