二维几何模板

终于完成了,先挂函数列表,然后是代码

所在行函数(结构)声明功能
23int sign(double d)返回浮点数的符号
24bool isint(double d)判断一个浮点数是不是整数
25bool Equal(double a,double b)判断两个浮点数是否相等
28struct Point点定义
13NAP不是一个点
34bool isnap(const Point& P)判断一个点是不是NAP
40typedef Point Vector;向量定义
42Vector operator + (Vector A,Vector B)向量相加
43Vector operator - (Vector A,Vector B)向量相减
44Vector operator * (Vector A,double t)数乘向量
45Vector operator * (double t,Vector A)数乘向量
46Vector operator / (Vector A,double t)向量除数
49bool operator < (const Point& a,const Point& b)坐标从左到右从下到上的比较
50bool operator == (const Point& a,const Point& b)坐标从左到右从下到上的比较
51bool operator > (const Point& a,const Point& b)坐标从左到右从下到上的比较
52bool operator <= (const Point& a,const Point& b)坐标从左到右从下到上的比较
53bool operator >= (const Point& a,const Point& b)坐标从左到右从下到上的比较
55double Dot(const Point& A,const Point& B)点积
56double Cross(const Point& A,const Point& B)叉积
57double Length(const Point& A)
58double Length(const Point& A,const Point& B)两点间距
59double Distance(const Point& A,const Point& B)两点间距
60double Angle(const Point& A,const Point& B)两向量夹角
61double Area2(const Point& A,const Point& B,const Point& C)三角形有向面积
63Vector Rotate(const Vector& A,double rad)向量绕起点旋转rad弧度
64Vector Normal(const Vector& A)单位法向量
65Vector Unit(const Vector& A)单位向量
67bool Collinear(const Point& A,const Point& B,const Point& C)判断三点是否共线
72struct Segment线段定义
77struct Line直线定义
14NAS不是一个线段(直线)
84bool isnas(const Segment& S)判断是否为NAS
91bool Online(const Point& P,const Line& L)点在直线上
92bool Online(const Point& P,const Segment& L)点在线段上 不包括端点
93bool Online_ex(const Point& P,const Segment& L)点在线段上 包括端点
95int Side(const Point& P,Line L)点对于直线的位置
96int Side(const Point& P,Segment L)点对于直线的位置
97bool SameSide(const Point& P1,const Point& P2,const Line& L)两点在直线同侧判定 不包含在直线上
98bool SameSide(const Point& P1,const Point& P2,const Segment& L)两点在线段同侧判定 不包含在线段所在直线上
99bool SameSide_ex(const Point& P1,const Point& P2,const Line& L)两点在直线同侧判定 包含在直线上
100bool SameSide_ex(const Point& P1,const Point& P2,const Segment& L)两点在线段同侧判定 包含在线段所在直线上
103bool Parallel(const Line& L1,const Line& L2)平行或重合判定
104Equal(const Line& L1,const Line& L2)重合判定
105bool operator == (const Line& L1,const Line& L2)重合判定
106bool Vertical(const Line& L1,const Line& L2)垂直判定
109bool Parallel(const Segment& L1,const Segment& L2)线段平行或共线
110bool Collinear(const Segment& L1,const Segment& L2)判定共线
111bool Equal(const Segment& L1,const Segment& L2)线段相等判定
112bool operator == (const Segment& L1,const Segment& L2)线段相等判定
113bool Intersec(const Segment& L1,const Segment& L2)判断两线段是否相交 不包括端点
114bool Intersec_ex(const Segment& L1,const Segment& L2)判断两线段是否相交 包括端点
122double Distance(const Line& L,const Point& P)点到直线距离
123double Distance(const Segment& S,const Point& P)点到线段距离
131double Length(const Segment& S)线段长度
133Point Intersection(const Line& L1,const Line& L2)两直线交点
140Point Intersection(const Segment& L1,const Segment& L2)两线段交点 不包含端点
146Point Intersection_ex(const Segment& L1,const Segment& L2)两线段交点 包含端点
153Point LineSymmetry(const Line&symmetryline,const Point& P)点关于直线的对称点
160Point LineSymmetry(const Segment&symmetryline,const Point& P)点关于线段的对称点
167Line LineSymmetry(const Line&symmetryline,const Line& L)直线关于直线的对称线
170Segment LineSymmetry(const Line&symmetryline,const Segment& L)线段关于直线的对称线
173Line LineSymmetry(const Segment&symmetryline,const Line& L)直线关于线段的对称线
176Segment LineSymmetry(const Segment&symmetryline,const Segment& L)线段关于线段的对称线
179Point PointSymmetry(const Point&symmetrypoint,const Point& P)中心对称
181Segment PointSymmetry(const Point&Symmetrypoint,const Segment& L)线段关于点的中心对称
184Line PointSymmetry(const Point&Symmetrypoint,const Line& L)直线关于点的中心对称
189Point Projection(const Line& L,const Point& P)点在直线上的投影
196Point Projection(const Segment& L,const Point& P)点对线段的投影
203Segment Projection(const Line& L,const Segment& S)线段在直线上的投影
210Point Midpoint(const Segment& S)中点
212Line Perpendicular(const Line& S,const Point& P)过定点的垂线
213Line PerpendicularBisector(const Segment& S)垂直平分线
215Line NormalLine(const Line& S,const Point& P)过定点垂线
216Line Midnormal(const Segment& S)垂直平分线
218Line AngleBisector(const Line& L1,const Line& L2)角平分线
232double Area(const Point& A,const Point& B,const Point& C)三角形面积
234Point Circumcenter(const Point& A,const Point& B,const Point& C)三角形外心
237Point Incenter(const Point& A,const Point& B,const Point& C)三角形内心
241Point Perpencenter(const Point& A,const Point& B,const Point& C)三角形垂心
244Point Barycentry(const Point& A,const Point& B,const Point& C)三角形重心
247struct Triangle三角形定义
254double Area(const Triangle& T)三角形面积
255Point Circumcenter(const Triangle& T)三角形外心
256Point Incenter(const Triangle& T)三角形内心
257Point Perpencenter(const Triangle& T)三角形垂心
258Point Barycentry(const Triangle& T)三角形重心
260int Type(const Triangle& T)返回三角形的类型
263bool InTriangle_ex(const Point& P,const Triangle& T)返回点是否在三角形内部(含边)
266bool InTriangleLine(const Point& P,const Triangle& T)返回点是否在三角形边上(含端点)
269bool InTriangle(const Point& P,const Triangle& T)返回点是否在三角形内部(不含边)
276struct Polygon多边形定义
312double Area(const Polygon& P)多边形的面积
322Polygon ConvexHull_ex(Polygon P)凸包扫描算法(含平角)
343int ConvexHull_ex(int n,Point *P,Point *ans)凸包扫描算法(含平角)
351Polygon ConvexHull(Polygon P)凸包扫描算法(不含平角)
372int ConvexHull(int n,Point *P,Point *ans)凸包扫描算法(不含平角)
380bool IsConvex(const Polygon& P)判断是否为凸多边形 (凸多边形定义包含平角)
389bool IsConvex(int n,Point *P)判断是否为凸多边形
394int InPolygon(const Point& P,const Polygon& POLY)点是否在多边形内部
412struct Circle圆的定义
419double Area(const Circle& C)圆的面积
421int Position(const Point& P,const Circle& C)返回点与圆的位置关系
426int Position(const Line& L,const Circle& C)返回直线与圆的位置关系
431Segment Intersection(const Line& L,const Circle& C)返回直线与圆的割线
453int Position(const Circle& C1,const Circle& C2)圆与圆的位置关系
471Segment Intersection(const Circle& C1,const Circle& C2)圆与圆的公共弦

欢迎纠错帮忙改进,转载请注明出处 

/*************************************二维几何模板***************************************************/


/*************************** lc思念落叶(sinianluoye、JLU_Lichuang) 2015-3-10***********************/


#include <cmath>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>


#define eps 1e-8
#define sqr(x) ((x)*(x))
#define NAP Point(NAN,NAN)
#define NAS Segment(NAP,NAP)




using namespace std;


/***1.点与向量的基本定义***/


const double pi=acos(-1);


int sign(double d){if(fabs(d)<eps)return 0;return (d<0)?-1:1;} ///返回浮点数的符号
bool isint(double d){return fabs(floor(d+0.5)-d)<eps;} ///判断一个浮点数是不是整数
bool Equal(double a,double b){return fabs(a-b)<eps;}///判断两个浮点数是否相等




struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};


bool isnap(const Point& P)
{
    return isnan(P.x)||isnan(P.y);
}




typedef Point Vector;


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,double t){return Vector(A.x*t,A.y*t);}///数乘向量
Vector operator * (double t,Vector A){return Vector(A.x*t,A.y*t);}///数乘向量
Vector operator / (Vector A,double t){return Vector(A.x/t,A.y/t);}///向量除数


/**以下比较基于点的坐标从左到右从下到上**/
bool operator < (const Point& a,const Point& b){if(sign(a.x-b.x))return a.x<b.x;return a.y<b.y;}
bool operator == (const Point& a,const Point& b){return !(sign(a.x-b.x)||sign(a.y-b.y));}
bool operator > (const Point& a,const Point& b){return !((a<b)||(a==b));}
bool operator <= (const Point& a,const Point& b){return !(a>b);}
bool operator >= (const Point& a,const Point& b){return !(a<b);}


double Dot(const Point& A,const Point& B){return A.x*B.x+A.y*B.y;}///点积
double Cross(const Point& A,const Point& B){return A.x*B.y-A.y*B.x;}///叉积
double Length(const Point& A){return sqrt(Dot(A,A));}///模
double Length(const Point& A,const Point& B){return Length(A-B);}///两点间距
double Distance(const Point& A,const Point& B){return Length(A-B);}///两点间距
double Angle(const Point& A,const Point& B){return acos(Dot(A,B)/Length(A)/Length(B));}///两向量夹角
double Area2(const Point& A,const Point& B,const Point& C){return 0.5*Cross(B-A,C-A);}///三角形的有向面积


Vector Rotate(const Vector& A,double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}///向量绕起点旋转rad弧度
Vector Normal(const Vector& A){double L=Length(A);return Vector(-A.y/L,A.x/L);}///单位法向量
Vector Unit(const Vector& A){double L=Length(A);return Vector(A.x/L,A.y/L);}///单位向量


bool Collinear(const Point& A,const Point& B,const Point& C){return !sign(Cross(A-B,A-C));}///判断三点是否共线


/***2.直线射线线段相关***/
///a,b为线段的两端点(直线上的两点) v为方向向量


struct Segment
{
    Point a,b,v;
    Segment(Point a=Point(),Point b=Point()):a(a),b(b),v(b-a){}
};///线段
struct Line
{
    Point a,b,v;
    Line(Point a=Point(),Point b=Point()):a(a),b(b),v(b-a){}
    Line(Segment S):a(S.a),b(S.b),v(S.v){}
};///直线


bool isnas(const Segment& S)
{
    return isnap(S.a)||isnap(S.b);
}


///点与直线线段的位置关系


bool Online(const Point& P,const Line& L){return !sign(Cross(P-L.a,L.v));}///点在直线上
bool Online(const Point& P,const Segment& L){return (Online(P,Line(L))&&(sign(Dot(P-L.a,L.v))>0)&&(sign(Dot(L.b-P,L.v))>0));}///点在线段上 不包括端点
bool Online_ex(const Point& P,const Segment& L){return (Online(P,Line(L))&&(sign(Dot(P-L.a,L.v))>=0)&&(sign(Dot(L.b-P,L.v))>=0));}///点在线段上 包括端点


int Side(const Point& P,Line L){if(L.a>L.b)swap(L.a,L.b);return sign(Area2(L.a,L.b,P));}///返回点对于直线的位置 1(左(上)边) 0(在直线上) -1在(右(下)边)
int Side(const Point& P,Segment L){if(L.a>L.b)swap(L.a,L.b);return sign(Area2(L.a,L.b,P));}///返回点对于直线的位置 1(左(上)边) 0(在线段所在直线上) -1在(右(下)边)
bool SameSide(const Point& P1,const Point& P2,const Line& L){return Side(P1,L)*Side(P2,L)==1;}///两点在直线同侧判定 不包含在直线上
bool SameSide(const Point& P1,const Point& P2,const Segment& L){return Side(P1,L)*Side(P2,L)==1;}///两点在线段同侧判定 不包含在线段所在直线上
bool SameSide_ex(const Point& P1,const Point& P2,const Line& L){return Side(P1,L)*Side(P2,L)>=0;}///两点在直线同侧判定 包含在直线上
bool SameSide_ex(const Point& P1,const Point& P2,const Segment& L){return Side(P1,L)*Side(P2,L)>=0;}///两点在线段同侧判定 包含在线段所在直线上


///直线位置关系
bool Parallel(const Line& L1,const Line& L2){return !sign(Cross(L1.v,L2.v));}///平行和重合都返回1 注意重合!!!
bool Equal(const Line& L1,const Line& L2){Line T(L1.a,L2.a);return Parallel(L1,L2)&&Parallel(L1,T);}///重合判定
bool operator == (const Line& L1,const Line& L2){return Equal(L1,L2);}
bool Vertical(const Line& L1,const Line& L2){return !sign(Dot(L1.v,L2.v));}///垂直判定


///线段位置关系
bool Parallel(const Segment& L1,const Segment& L2){return !sign(Cross(L1.v,L2.v));}///线段平行或共线都返回1 注意共线!!!
bool Collinear(const Segment& L1,const Segment& L2){return Parallel(L1,L2)&&Collinear(L1.a,L1.b,L2.a);}///判定共线
bool Equal(const Segment& L1,const Segment& L2){return L1.a==L2.a&&L1.b==L2.b;}///线段相等判定
bool operator == (const Segment& L1,const Segment& L2){return Equal(L1,L2);}
bool Intersec(const Segment& L1,const Segment& L2){return ((Side(L1.a,L2)*Side(L1.b,L2))<0)&&(Side(L2.a,L1)*Side(L2.b,L1)<0);}///判断两线段是否相交不包括端点
bool Intersec_ex(const Segment& L1,const Segment& L2)
{
    int s1=Side(L1.a,L2),s2=Side(L1.b,L2),s3=Side(L2.a,L1),s4=Side(L2.b,L1);
    return (s1||s2)&&(s3||s4);
}///判断两线段是否相交包括端点


///交点、对称点、距离


double Distance(const Line& L,const Point& P){return fabs(Cross(P-L.a,L.v)/Length(L.v));}///点到直线距离
double Distance(const Segment& S,const Point& P)///点到线段距离
{
    if(sign(Dot(P-S.a,S.v))<=0)
        return Distance(P,S.a);
    if(sign(Dot(P-S.b,S.v))<=0)
        return Distance(P,S.b);
    return fabs(Cross(P-S.a,S.v)/Length(S.v));
}
double Length(const Segment& S){return Length(S.a,S.b);}///线段长度


Point Intersection(const Line& L1,const Line& L2)///两直线交点 请先判断是否平行
{
    Vector u=L1.a-L2.a;
    double t=Cross(L2.v,u)/Cross(L1.v,L2.v);
    return L1.a+L1.v*t;
}


Point Intersection(const Segment& L1,const Segment& L2)///两线段交点 不包含端点 不相交的线段返回(NAN,NAN)
{
    if(Intersec(L1,L2))
        return Intersection(Line(L1),Line(L2));
    return NAP;
}
Point Intersection_ex(const Segment& L1,const Segment& L2)///两线段交点 包含端点 不相交的线段返回(NAN,NAN)
{
    if(Intersec_ex(L1,L2))
        return Intersection(Line(L1),Line(L2));
    return NAP;
}


Point LineSymmetry(const Line&symmetryline,const Point& P)///点关于直线的对称点
{
    Vector u=P-symmetryline.a,v=Normal(symmetryline.v),w=symmetryline.v;
    double t=Cross(w,u)/Cross(v,w);
    return P+2*t*v;
}


Point LineSymmetry(const Segment&symmetryline,const Point& P)///点关于线段的对称点
{
    Vector u=P-symmetryline.a,v=Normal(symmetryline.v),w=symmetryline.v;
    double t=Cross(w,u)/Cross(v,w);
    return P+2*t*v;
}


Line LineSymmetry(const Line&symmetryline,const Line& L)///直线关于直线的对称线
{return Line(LineSymmetry(symmetryline,L.a),LineSymmetry(symmetryline,L.b));}


Segment LineSymmetry(const Line&symmetryline,const Segment& L)///线段关于直线的对称线
{return Segment(LineSymmetry(symmetryline,L.a),LineSymmetry(symmetryline,L.b));}


Line LineSymmetry(const Segment&symmetryline,const Line& L)///直线关于线段的对称线
{return Line(LineSymmetry(symmetryline,L.a),LineSymmetry(symmetryline,L.b));}


Segment LineSymmetry(const Segment&symmetryline,const Segment& L)///线段关于线段的对称线
{return Segment(LineSymmetry(symmetryline,L.a),LineSymmetry(symmetryline,L.b));}


Point PointSymmetry(const Point&symmetrypoint,const Point& P){return 2*symmetrypoint-P;}///中心对称


Segment PointSymmetry(const Point&Symmetrypoint,const Segment& L)///线段关于点的中心对称
{return Segment(PointSymmetry(Symmetrypoint,L.a),PointSymmetry(Symmetrypoint,L.b));}


Line PointSymmetry(const Point&Symmetrypoint,const Line& L)///直线关于点的中心对称
{return Segment(PointSymmetry(Symmetrypoint,L.a),PointSymmetry(Symmetrypoint,L.b));}






Point Projection(const Line& L,const Point& P)///点在直线上的投影
{
    Vector u=P-L.a,v=Normal(L.v),w=L.v;
    double t=Cross(w,u)/Cross(v,w);
    return P+t*v;
}


Point Projection(const Segment& L,const Point& P)///点对线段的投影(不一定在线段上)
{
    Vector u=P-L.a,v=Normal(L.v),w=L.v;
    double t=Cross(w,u)/Cross(v,w);
    return P+t*v;
}


Segment Projection(const Line& L,const Segment& S)///线段在直线上的投影
{
    return Segment(Projection(L,S.a),Projection(L,S.b));
}




///线段相关
Point Midpoint(const Segment& S){return 0.5*(S.a+S.b);}///中点


Line Perpendicular(const Line& S,const Point& P){return Line(P,P+Normal(S.v));}///过定点的垂线
Line PerpendicularBisector(const Segment& S){return Perpendicular(S,Midpoint(S));}///垂直平分线


Line NormalLine(const Line& S,const Point& P){return Line(P,P+Normal(S.v));}///过定点垂线(上边的名太长了 这个好记些 下同)
Line Midnormal(const Segment& S){return Perpendicular(S,Midpoint(S));}///垂直平分线


Line AngleBisector(const Line& L1,const Line& L2)///角平分线
///注意这里L1 L2为射线 方向分别为 L1.v即(L1.b-L1.a),L2.v即(L2.b-L2.a) 函数输入只需保证方向正确且L1,L2不平行即可
{
    Point P=Intersection(L1,L2);
    Vector V=Unit(L1.v)+Unit(L2.v);
    if(Length(V)>eps)
    return Line(P,P+V);
    return NormalLine(L1,L1.a);
}


/********************************二维图形相关**********************************************/


///三角形


double Area(const Point& A,const Point& B,const Point& C){return fabs(Area2(A,B,C));}///三角形面积


Point Circumcenter(const Point& A,const Point& B,const Point& C)
{return Intersection(Midnormal(Segment(A,B)),Midnormal(Segment(A,C)));}///三角形外心


Point Incenter(const Point& A,const Point& B,const Point& C)
{return Intersection(AngleBisector(Line(A,B),Line(A,C)),AngleBisector(Line(B,C),Line(B,A)));}///三角形内心




Point Perpencenter(const Point& A,const Point& B,const Point& C)
{return Intersection(Perpendicular(Line(A,B),C),Perpendicular(Line(A,C),B));}/// 三角形垂心


Point Barycentry(const Point& A,const Point& B,const Point& C)
{return (A+B+C)/3.0;}///三角形重心


struct Triangle
{
    Point A,B,C;
    Triangle(Point A=Point(),Point B=Point(),Point C=Point())
    :A(A),B(B),C(C){}
};


double Area(const Triangle& T){return Area(T.A,T.B,T.C);}///面积
Point Circumcenter(const Triangle& T){return Circumcenter(T.A,T.B,T.C);}///外心
Point Incenter(const Triangle& T){return Incenter(T.A,T.B,T.C);}///内心
Point Perpencenter(const Triangle& T){return Perpencenter(T.A,T.B,T.C);}///垂心
Point Barycentry(const Triangle& T){return Barycentry(T.A,T.B,T.C);}///重心


int Type(const Triangle& T)///返回三角形的类型 -1 钝角 0直角 1 锐角
{return sign(Dot(T.A-T.B,T.A-T.C)*Dot(T.B-T.A,T.B-T.C)*Dot(T.C-T.A,T.C-T.B));}


bool InTriangle_ex(const Point& P,const Triangle& T)///返回点是否在三角形内部(含边)
{return !sign(Area(P,T.A,T.B)+Area(P,T.A,T.C)+Area(P,T.B,T.C)-Area(T));}


bool InTriangleLine(const Point& P,const Triangle& T)///返回点是否在三角形边上(含端点)
{return Online_ex(P,Segment(T.A,T.B))||Online_ex(P,Segment(T.A,T.C))||Online_ex(P,Segment(T.C,T.B));}


bool InTriangle(const Point& P,const Triangle& T)///返回点是否在三角形内部(不含边)
{return InTriangle_ex(P,T)&&!InTriangleLine(P,T);}






///多边形


struct Polygon
{
    int n;
    Point *P;
    Polygon(int nums=0,Point *point=NULL)
    {
        if(nums>2)
        {
            P=new Point[n=nums];
            for(int i=0;i<n;i++)
                P[i]=point[i];
        }
        else
        {
            n=0,P=NULL;
        }
    }


    Polygon(const Polygon& T)
    {
        n=T.n;
        P=new Point[n];
        for(int i=0;i<n;i++)
            P[i]=T[i];
    }


    Point& operator [](int key)
    {
        return P[key];
    }
    const Point& operator [](int key)const
    {
        return P[key];
    }
};


double Area(const Polygon& P)///多边形的面积
{
    double ret=0;
    for(int i=1;i<P.n-1;i++)
    {
        ret+=Area2(P[0],P[i],P[i+1]);
    }
    return fabs(ret);
}


Polygon ConvexHull_ex(Polygon P)///凸包扫描算法(含平角)
{
    sort(P.P,P.P+P.n);
    Polygon ret(P.n,P.P);
    int n=P.n,&m=P.n;
    m=0;
    for(int i=0;i<n;i++)
    {
        while(m>1&&sign(Cross(ret[m-1]-ret[m-2],P[i]-ret[m-2]))<0)m--;
        ret[m++]=P[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&sign(Cross(ret[m-1]-ret[m-2],P[i]-ret[m-2]))<0)m--;
        ret[m++]=P[i];
    }
    if(m>1)m--;
    return ret;
}


int ConvexHull_ex(int n,Point *P,Point *ans)///凸包扫描算法(含平角)
{
    Polygon ret=ConvexHull_ex(Polygon(n,P));
    for(int i=0;i<ret.n;i++)
        ans[i]=ret[i];
    return ret.n;
}


Polygon ConvexHull(Polygon P)///凸包扫描算法(不含平角)
{
    sort(P.P,P.P+P.n);
    Polygon ret(P.n,P.P);
    int n=P.n,&m=P.n;
    m=0;
    for(int i=0;i<n;i++)
    {
        while(m>1&&sign(Cross(ret[m-1]-ret[m-2],P[i]-ret[m-2]))<=0)m--;
        ret[m++]=P[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&sign(Cross(ret[m-1]-ret[m-2],P[i]-ret[m-2]))<=0)m--;
        ret[m++]=P[i];
    }
    if(m>1)m--;
    return ret;
}


int ConvexHull(int n,Point *P,Point *ans)///凸包扫描算法(不含平角)
{
    Polygon ret=ConvexHull(Polygon(n,P));
    for(int i=0;i<ret.n;i++)
        ans[i]=ret[i];
    return ret.n;
}


bool IsConvex(const Polygon& P)///判断是否为凸多边形 (凸多边形定义包含平角)
{
    if(P.n<=3)return 1;
    int t=sign(Area2(P[0],P[1],P[2]));
    for(int i=1;i<P.n-2;i++)
        if(t*sign(Area2(P[i],P[i+1],P[i+2]))<0)return 0;
    return 1;
}


bool IsConvex(int n,Point *P)///判断是否为凸多边形
{
    return IsConvex(Polygon(n,P));
}


int InPolygon(const Point& P,const Polygon& POLY)///返回点是(1)否(0)在多边形内部 负数为在PLOY[-i]和[(-i+1)%n]的线段上
{
    int ret=0,n=POLY.n;
    for(int i=0;i<n;i++)
    {
        if(Online_ex(P,Segment(POLY[i],POLY[(i+1)%n])))
            return -i;
        int t=sign(Cross(POLY[(i+1)%n]-POLY[i],P-POLY[i]));
        int d1=sign(POLY[i].y-P.y);
        int d2=sign(POLY[(i+1)%n].y-P.y);
        if(t>0&&d1<=0&&d2>0)ret++;
        if(t<0&&d2<=0&&d1>0)ret--;
    }
    return ret!=0;
}


///圆


struct Circle
{
    Point C;
    double r;
    Circle(Point C=Point(),double r=0.0):C(C),r(r){}
};


double Area(const Circle& C){return pi*sqr(C.r);}


int Position(const Point& P,const Circle& C)///返回点与圆的位置关系 -1 内部 0 圆上 1 外部
{
    return sign(Length(P,C.C)-C.r);
}


int Position(const Line& L,const Circle& C)///返回直线与圆的位置关系 -1 相离 0 相切 1 相交
{
    return -sign(Distance(L,C.C)-C.r);
}


Segment Intersection(const Line& L,const Circle& C)
///返回直线与圆的交点 相交时返回割线(两端点即为交点) 相切时返回切点(返回线段的两个端点都相同)
///相离时返回 NAS
{
    double d=sqr(C.r)-sqr(Distance(L,C.C));
    if(sign(d)>0)
    {
        d/=Dot(L.v,L.v);
        d=sqrt(d);
        double dx=L.v.x*d,dy=L.v.y*d;
        Point t=Projection(L,C.C),D(dx,dy);
        return Segment(t+D,t-D);
    }
    else if(sign(d)==0)
    {
        Point ret=Projection(L,C.C);
        return Segment(ret,ret);
    }
    else
        return NAS;
}


int Position(const Circle& C1,const Circle& C2)
/// 圆与圆的位置关系
///0 相交 1 外切 -1内切 2 相离 -2 内含
{
    double d=Distance(C1.C,C2.C);
    switch(sign(d-C1.r-C2.r))
    {
    case -1:return 2;
    case 0:return 1;
    }
    switch(sign(fabs(C1.r-C2.r)-d))
    {
    case 0:return -1;
    case 1:return -2;
    }
    return 0;
}


Segment Intersection(const Circle& C1,const Circle& C2)
/// 圆与圆的公共弦 不相交返回 NAS
{
    int key=Position(C1,C2);
    if(!key)
    {
        double d=Distance(C1.C,C2.C);
        double s=C1.r+C2.r+d;
        s/=2;
        double h2=4.0*s*(s-C1.r)*(s-C2.r)*(s-d)/d/d;
        double l=sqrt(sqr(C1.r)-h2);
        Point D=(C2.C-C1.C)*(l/d)+C1.C;
        double h=sqrt(h2);
        Line L=NormalLine(Line(C1.C,C2.C),D);
        return Intersection(L,C1);
    }
    else if(abs(key)==1)
    {
        Point ret=C1.r/(Distance(C1.C,C2.C))*(C2.C-C1.C)+C1.C;
        return Segment(ret,ret);
    }
    else return NAS;
}


/*************copyright by sinianluoye (JLU_LiChuang)***********/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值