文章標題 計算幾何

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue> 
#include<algorithm>
using namespace std;
const double pi=acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn=100005;
const double eps=1e-8; 
//精度函數 
int sgn(double x){
    if (fabs(x)<eps)return 0;
    if (x<0) return -1;
    return 1;
}

struct point {
    double x,y;
    point (double a=0,double b=0){
        x=a;y=b;
    }
    bool operator <(const point &t){
        return (x<t.x)||(x==t.x&&y<t.y);
    }
    //相減 
    point operator - (const point &b)const {
        return point(x-b.x,y-b.y);
    }
    //叉積
    double operator ^ (const point &b)const{
        return x*b.y-y*b.x;
    } 
    //點積
    double operator * (const point &b) const {
        return x*b.x+y*b.y;
    }
    //繞原點旋轉角度B(弧度值),後x,y的變化 ,返回點 
    point transXY(double B){
        double tx=x,ty=y;
        x = tx*cos(B) - ty*sin(B);   
        y = tx*sin(B) + ty*cos(B); 
        return point(x,y);
    }
}; 

struct line{
    point s,e;
    line(){}
    line (point x,point y){
        s=x,e=y;
    }
    //兩直線相交求交點  
    //第一個值爲0表示直線重合,爲1表示平行,爲0表示相交,爲2是相交  
    //只有第一個值爲2時,交點纔有意義
    pair<int,point> operator &(const line &b)const{         
        point res = s;         
        if(sgn((s-e)^(b.s-b.e)) == 0){             
            if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合             
            else return make_pair(1,res);//平行         
        }
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;         
        return make_pair(2,res);     
    } 
};

//計算多邊形面積 
//點的編號從0~n-1 
double calArea(point P[],int len){
    double ans=0;
    for (int i=0;i<len;i++){
        ans+=(P[i]^P[(i+1)%len])/2;
    }
    return fabs(ans);
}

//*判斷線段相交
bool inter(line l1,line l2){
    return 
    max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
    max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
    max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
    max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
    sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
    sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}

//求凸包
/*
計算凸包,輸入點數組p,個數爲n,輸出點數組ch,函數返回凸包定點的數
輸入不能有重複點。函數執行完之後輸入點的順序被破壞
如果不希望在凸包的邊上有輸出點,把兩個<=改成<
在精度也要求高時建議用sgn比較 
*/ 
int convexHull(point p[],int n,point ch[]){
    sort(p,p+n);
    int m=0;
    for (int i=0;i<n;i++){
        while (m>1&&(sgn(point(ch[m-1]-ch[m-2])^point(p[i]-ch[m-2])))<=0)m--;
        ch[m++]=p[i];
    }
    int k=m;
    for (int i=n-2;i>=0;i--){
        while (m>k&&(sgn(point(ch[m-1]-ch[m-2])^point(p[i]-ch[m-2])))<=0)m--;
        ch[m++]=p[i];
    }
    if (n>1)m--;
    return m;
} 

//二分判斷點A是否在凸包邊界上和內部裏面 ,ch表示凸包數組 
bool check(point A,int n){
    int l=1,r=n-2;
    while (l<=r){
        int mid=(r+l)/2;
        double a1=(ch[mid]-ch[0])^(A-ch[0]);
        double a2=(ch[mid+1]-p[0]^(A-ch[0]));
        if (sgn(a1)>=0&&sgn(a2)<=0){
            if (sgn((ch[mid+1]-ch[mid])^(A-ch[mid]))>=0)return true;
            return false;
        }
        if (a1<0)r=mid-1;
        else l=mid+1; 
    }
    return false;
} 


int main()
{

    return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章