文章标题 计算几何

来源:互联网 发布:田中真弓等级知乎 编辑:程序博客网 时间:2024/06/05 05:06
#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; } 
原创粉丝点击