待更新。。。
#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; }
时间: 2024-10-13 12:03:11