计算几何基础模板(点,线,圆)

#include
using namespace std;
const double eps=1e-8;
const double inf=1e20;
const double PI=acos(-1.0);
const int maxn=1e5+3;
int sgn(double x)
{
    if(fabs(x)0) return 2;//右
        else return 3;//线上
    }
    bool pointSeg(Point p)
    {
        return sgn((p-s)^(e-s))==0&&sgn((p-s)*(p-e))<=0;
    }
    int segcrossseg(Line v)//2 规范
    {//1非规  0 不交
        int d1 = sgn((e-s)^(v.s-s));
        int d2 = sgn((e-s)^(v.e-s));
        int d3 = sgn((v.e-v.s)^(s-v.s)); int d4 = sgn((v.e-v.s)^(e-v.s));
        if( (d1^d2)==-2 && (d3^d4)==-2 ) return 2;
        return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
        (d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
        (d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
        (d4==0 && sgn((e-v.s)*(e-v.e))<=0);
    }
    int linecrossseg(Line v)
    {
        int d1 = sgn((e-s)^(v.s-s));
        int d2 = sgn((e-s)^(v.e-s));
        if((d1^d2)==-2) return 2;
        return (d1==0||d2==0);//0 不交
    }
    bool parallel(Line v)
    {
        return sgn((e-s)^(v.e-v.s))==0;
    }
    int linecrossline(Line v)
    {
        if((*this).parallel(v))
        {
            return v.relation(s)==3;
        }
        return 2;//0 平行,1重和,2相交
    }
    Point crossPoint(Line v)
    {
        double a1=(v.e-v.s)^(s-v.s);
        double a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    }
    double length()
    {
        return s.distance(e);
    }
    double disPointLine(Point p)
    {
        return fabs(((p-s)^(e-s))/length());
    }
    double disPointSeg(Point p)
    {
        if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)
        {
            return min(p.distance(s),p.distance(e));
        }
        return disPointLine(p);
    }
    //返回点 p 在直线上的投影
};
struct circle
{
    Point p;//圆心
    double r;
    circle()=default;
    circle(Point a,double b):p(a),r(b){}
    circle(Point a,Point b,Point c)//三角行外接圆
    {
        Line u=Line((a+b)/2,( (a+b)/2+(b-a).rotleft()));
        Line v=Line( (b+c)/2 ,(b+c)/2+ ( (c-b).rotleft()));
        p=u.crossPoint(v);
        r=p.distance(a);
    }
    circle(Point a,Point b,Point c,bool t)//内接圆
    {
        Line u,v;
        double m = atan2(b.y-a.y,b.x-a.x), n = atan2(c.y-a.y,c.x-a.
        x);
        u.s = a;
        u.e = u.s + Point(cos((n+m)/2),sin((n+m)/2));
        v.s = b;
        m = atan2(a.y-b.y,a.x-b.x) , n = atan2(c.y-b.y,c.x-b.x);
        v.e = v.s + Point(cos((n+m)/2),sin((n+m)/2));
        p = u.crossPoint(v);
        r = Line(a,b).disPointSeg(p);
    }
    void input()
    {
        p.input();
        scanf("%lf",&r);
    }
    void output(){printf("%.2lf %.2lf %.2lf\n",p.x,p.y,r);}
    bool operator == (circle v){return (p==v.p)&&sgn(r-v.r)==0;}
    double area(){return PI*r;}//面积
    double circumference(){return 2*PI*r;}//周长
    bool operator < (circle v)const{ return ((p 0)return 5;   //4 外切
        if(sgn(d-r-v.r) == 0)return 4;  //3 相交
        double l = fabs(r-v.r); //2 内切
        if(sgn(d-r-v.r)<0 && sgn(d-l)>0)return 3;   //1 内含
        if(sgn(d-l)==0)return 2;
        if(sgn(d-l)<0)return 1;
    }


//求两个圆的交点,返回 0 表示没有交点,返回 1 是一个交点,2 是两个交点
    int pointcrosscircle(circle v,Point &p1,Point &p2)
    {
        int rel = relationcircle(v);
        if(rel == 1 || rel == 5)return 0;
        double d = p.distance(v.p);
        double l = (d*d+r*r-v.r*v.r)/(2*d);
        double h = sqrt(r*r-l*l);
        Point tmp = p + (v.p-p).trunc(l);
        p1 = tmp + ((v.p-p).rotleft().trunc(h));
        p2 = tmp + ((v.p-p).rotright().trunc(h));
        if(rel == 2 || rel == 4)
            return 1;
        return 2;
    }

    //得到过 a,b 两点,半径为 r1 的两个圆
    int gercircle(Point a,Point b,double r1,circle &c1,circle &c2)
    {
        circle x(a,r1),y(b,r1);
        int t = x.pointcrosscircle(y,c1.p,c2.p);
        if(!t)return 0;
        c1.r = c2.r = r;
        return t;
    }   
};

 

你可能感兴趣的:(计算几何基础)