计算几何基本模板

待更新。。。

#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;
}

  

原文地址:https://www.cnblogs.com/td15980891505/p/5727921.html