待更新。。。
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const double PI = acos(-1);
const double EPS = 1e-8;//实数精度
//点结构类型
struct Point{
double x, y;
Point(double a = 0, double b = 0){ x = a; y = b; }
};
//线段结构类型
struct LineSeg{
Point s, e;
LineSeg();
LineSeg(Point a, Point b): s(a), e(b){}
};
struct Line{//直线结构类型
//直线a*x+b*y+c=0 (a>=0)
double a, b, c;
};
Point operator-(Point a, Point b){
return Point(a.x - b.x, a.y - b.y);
}
//重载==,判断点a,b是否相等
bool operator==(Point a, Point b){
return abs(a.x - b.x) < EPS&&abs(a.y - b.y) < EPS;
}
//比较实数r1与r2的大小关系
int RlCmp(double r1, double r2 = 0){
if (abs(r1 - r2) < EPS)
return 0;
return r1>r2 ? 1 : -1;
}
//先比较横坐标再比较纵坐标,确定顺序,一般用在sort中
bool Cmp(Point a, Point b){
if (abs(a.x - b.x)<EPS)
return a.y < b.y;
else
return a.x < b.x;
}
//返回两点间的距离
double Distance(Point a, Point b){
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
//返回向量p1-p0和p2-p0的点积
double Dot(Point p0, Point p1, Point p2){
Point a = p1 - p0;
Point b = p2 - p0;
return a.x*b.x + a.y*b.y;
}
//返回向量p1-p0和p2-p0的叉积
double Cross(Point p0, Point p1, Point p2){
Point a = p1 - p0;
Point b = p2 - p0;
return a.x*b.y - b.x*a.y;
}
//判断点p是否规范在线段L上(不包括端点)
bool Standard_Online(LineSeg L, Point p){
return RlCmp(Cross(L.s, L.e, p)) == 0 &&
RlCmp(Dot(p, L.s, L.e))< 0;
}
//判断点p是在线段L上(包括端点)
bool Standard_Online(LineSeg L, Point p){
return RlCmp(Cross(L.s, L.e, p)) == 0 &&
RlCmp(Dot(p, L.s, L.e))<=0;
}
//返回将点p沿着原点逆时针旋转alpha(弧度制)角度得到的点
Point Rotate(Point p,double alpha=PI/2){
return Point(p.x*cos(alpha) - p.y*sin(alpha), p.x*sin(alpha) + p.y*cos(alpha));
}
//判断线段L1与线段L2是否相交(包括交点在线段上)
bool Intersect(LineSeg L1, LineSeg L2){
//排斥实验和跨立实验
return max(L1.s.x, L1.e.x) >= min(L2.s.x, L2.e.x)
&& min(L1.s.x, L1.e.x) <= max(L2.s.x, L2.e.x)
&& max(L1.s.y, L1.e.y) >= min(L2.s.y, L2.e.y)
&& min(L1.s.y, L1.e.y) <= max(L2.s.y, L2.e.y)
&& Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e) <= 0
&& Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e) <= 0;
}
//判断线段L1与L2是否规范相交
bool Standard_Intersect(LineSeg L1, LineSeg L2){
return RlCmp((Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e))) < 0
&& RlCmp((Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e)))< 0;
}
//两不同点a,b来构造直线
Line MakeLine(Point a, Point b){
Line L;
L.a = (b.y -a.y);
L.b = (a.x - b.x);
L.c = (b.x*a.y - a.x*b.y);
if (L.a < 0){ //保准x系数大于等于0
L.a = -L.a;
L.b = -L.b;
L.c = -L.c;
}
return L;
}
//判直线X,Y是否相交,相交返回true和交点
bool LineIntersect(Line X, Line Y, Point&P){
double d = X.a*Y.b - Y.a*X.b;
if (d == 0) //直线平行或者重合
return false;
P.x = (X.b*Y.c - Y.b*X.c) / d;
P.y = (X.c*Y.a - Y.c*X.a) / d;
return true;
}