#平面几何常用模板

####**定义点的类** ``` struct Point{ double x,y; Point(double x,double y):x(x),y(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 p){ return Vector(A.x/p,A.y/p);}
Vector operator * (Vector A,double p){ return Vector(A.xp,A.yp);}
double angle(Vector v)//求向量的角度从0到2*pi
{
return atan2(v.y,v.x);
}

####**点的基本操作**

//比较两个点
bool operator < (const Point &a ,const Point &b)
{
return a.x <b.x||(a.x==b.x&&a.y < b.y);
}
//精度要求
const double eps = 1e-10;
//对于浮点数等于零的判断
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
else
return x < 0?-1:1;
}
//判断两个点是否相等
bool operator == (const Point &a,const Point &b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}

####**一些点和向量的基本操作**
```cpp
//点乘
double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}
//取模
double Length(Vector A) {return sqrt(A.x*A.x+A.y*A.y);}
//求两个向量的夹角
double Angle(Vector A,Vector B) 
{ return acos(Dot(A,B)/Length(A)/Length(B));}
//叉乘
double Cross(Vector A,Vector B) { return A.x*B.y - A.y*B.x;}
//求三角形的面积
double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}
//向量旋转
Vector Rotate(Vector A,double rad)
{
    return Vector (A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
//单位法线
Vector Normal(Vector A)
{
    double L = Length(A);
    return Vector(-A.y/L,A.x/L);
}

####关于直线的操作

//求直线的交点 //调用前确保直线有唯一交点,当且仅当Cross(v,w)非0 Point Get_Line_Intersection(Point P,Vector v,Point Q,Vector w) { Vector u = P - Q; double t = Cross(w,u)/Cross(v,w); return P+v*t; } //点到直线的距离 double Distance_To_Line(Point P,Point A,Point B) { Vector v1 = B-A,v2 = P-A; return fabs(Cross(v1,v2)/Length(v1)); } //求点在直线的投影点 Point Get_Line_Projection(Point P,Point A,Point B)//求投影点 { Vector v = B- A; return A + v*(Dot(v,P-A)/Dot(v,v)); } 

一些线段的操作

//点到线段的距离
double Distance_To_Segment(Point P,Point A,Point B)
{
    if(A==B) return Length(P-A);
    Vector v1 = B-A,v2 = P-A,v3 = P-B;
    if(dcmp(Dot(v1,v2))<0) return Length(v1);
    else if(dcmp(Dot(v1,v3))>0) return Length(v3);
    else return fabs(Cross(v1,v2))/Length(v1);
}
//线段相交判定 相交不在线段的端点
bool Segment_Proper_Intersection(Point a1,Point a2,Point b1,Point b2)
{
    double c1 =  Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1),
           c3 =  Cross(b2-b1,a2-b1),c4 = Cross(b2-b1,a1-b1);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}
//判断点是否在线段上(不包括端点)
bool Onsegment(Point p,Point a1,Point a2)
{
    return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}

应用 求多边形的面积


//多边形的有向面积
//方法一
double PolygonArea (Point * p,int n)
{
    double area = 0;
    for(int i = 1;i < n - 1; ++i)
    {
      area += Cross(p[i]-p[0],p[i+1]-p[0]);
    }
    return area/2;
}
//方法二
double PolygonArea2(Point *p,int n)
{
    double area = 0;
    for(int i = 0;i <= n-1; ++i)
    {
        if(i!=n-1)
            area += Cross(p[i],p[i+1]);
        else
            area += Cross(p[n-1],p[0]);
    }
    return area/2;
}


模版

#include <bits/stdc++.h> #define mem(ar,num) memset(ar,num,sizeof(ar)) #define me(ar) memset(ar,0,sizeof(ar)) #define lowbit(x) (x&(-x)) #define forn(i,n) for(int i = 0;i < n; ++i) using namespace std; typedef long long LL; typedef unsigned long long ULL; const int prime = 999983; const int INF = 0x7FFFFFFF; const LL INFF =0x7FFFFFFFFFFFFFFF; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-10; const LL mod = 1e9 + 7; struct Point { double x,y; Point(double x = 0,double y = 0):x(x),y(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 p) { return Vector(A.x/p,A.y/p); } Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); } double angle(Vector v)//求向量的角度从0到2*pi { return atan2(v.y,v.x); } int dcmp(double x) { if(fabs(x)<eps) return 0; else return x < 0?-1:1; } bool operator < (const Point &a,const Point &b) { if(dcmp(a.x-b.x)==0) return a.y<b.y; else return a.x<b.x; } bool operator == (const Point &a,const Point &b) { return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y); } double Dot(Vector A,Vector B) { return A.x*B.x+A.y*B.y; } double Length(Vector A) { return sqrt(A.x*A.x+A.y*A.y); } double Angle(Vector A,Vector B) { return acos(Dot(A,B)/Length(A)/Length(B)); } double Cross(Vector A,Vector B) { return A.x*B.y - A.y*B.x; } double Area2(Point A,Point B,Point C) { return Cross(B-A,C-A); } Vector Rotate(Vector A,double rad) { return Vector (A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); } Vector Normal(Vector A)//单位法线 { double L = Length(A); return Vector(-A.y/L,A.x/L); } //调用前确保直线有唯一交点,当且仅当Cross(v,w)非0 Point Get_Line_Intersection(Point P,Vector v,Point Q,Vector w) { Vector u = P - Q; double t = Cross(w,u)/Cross(v,w); return P+v*t; } double Distance_To_Line(Point P,Point A,Point B)//点到直线的距离 { Vector v1 = B-A,v2 = P-A; return fabs(Cross(v1,v2)/Length(v1)); } double Distance_To_Segment(Point P,Point A,Point B) { if(A==B) return Length(P-A); Vector v1 = B-A,v2 = P-A,v3 = P-B; if(dcmp(Dot(v1,v2))<0) return Length(v1); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1); } Point Get_Line_Projection(Point P,Point A,Point B)//求投影点 { Vector v = B- A; return A + v*(Dot(v,P-A)/Dot(v,v)); } //线段相交判定 相交不在线段的端点 bool Segment_Proper_Intersection(Point a1,Point a2,Point b1,Point b2) { double c1 = Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1), c3 = Cross(b2-b1,a2-b1),c4 = Cross(b2-b1,a1-b1); return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0; } //判断点是否在线段上(不包括端点) bool Onsegment(Point p,Point a1,Point a2) { return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0; }