计算几何 全板
#include<bits/stdc++.h> #include<iostream> using namespace std; typedef long long ll; const double pi = acos(-1.0); const double inf = 1e100; const double eps = 1e-6; struct point { double x,y; point(double a = 0, double b = 0) { x=a; y=b; } }; point lst[1000]; int stk[1000],top=0; int dcmp(double x, double y){ if(fabs(x - y) < eps) return 0; if(x > y) return 1; return -1; } int sgn(double d){ if(fabs(d) < eps) return 0; if(d > 0) return 1; return -1; } typedef point Vector; typedef point Point; point operator +(point a,point b) { point temp; temp.x=a.x+b.x; temp.y=a.y+b.y; return temp; } point operator -(point a,point b) { point temp; temp.x=a.x-b.x; temp.y=a.y-b.y; return temp; } 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 Dot(point a,point b) { return a.x*b.x+a.y*b.y; } //叉积 double Cross(point a,point b) { return a.x*b.y-a.y*b.x; } //返回向量长度 double Length(Vector a) { return sqrt(Dot(a,a)); } double Dis(Point p1, Point p2) { //计算 p1p2的 距离 return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)); } //返回向量夹角 double Angle(Vector a,Vector b) { return asin(Cross(a,b)/Length(a)/Length(b)); } //判断是否左转 bool ToLeftTest(Vector a,Vector b) { return Cross(a,b)>0;//叉积的sinθ角来判断 } //求交点 前提 不相互平行 point GetlineIntersection(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 DistanceToLine(point P, point A, point B) { Vector v1 = B-A, v2 = P-A; return fabs(Cross(v1, v2)/Length(v1)); } //点P在直线AB上的投影点 Point GetLineProjection(Point P, Point A, Point B){ Vector v = B-A; return A+v*(Dot(v, P-A)/Dot(v, v)); } //点是否在线段上 bool OnSegment(Point p, Point a1, Point a2){ return dcmp(Cross(a1-p, a2-p),0) == 0 && dcmp(Dot(a1-p, a2-p),0) < 0; } //允许在端点处相交的线段判断 bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){ double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1); double c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1); //if判断控制是否允许线段在端点处相交,根据需要添加 if(!sgn(c1) || !sgn(c2) || !sgn(c3) || !sgn(c4)){ bool f1 = OnSegment(b1, a1, a2); bool f2 = OnSegment(b2, a1, a2); bool f3 = OnSegment(a1, b1, b2); bool f4 = OnSegment(a2, b1, b2); bool f = (f1|f2|f3|f4); return f; } return (sgn(c1)*sgn(c2) < 0 && sgn(c3)*sgn(c4) < 0); } //求多边形面积 double PolygonArea(Point* p, int n){//p为端点集合,n为端点个数 double s = 0; for(int i = 1; i < n-1; ++i) s += Cross(p[i]-p[0], p[i+1]-p[0]); return s; } //判断点是否在多边形内,若点在多边形内返回1,在多边形外部返回0,在多边形上返回-1 int isPointInPolygon(Point p, vector<Point> poly){ int wn = 0; int n = poly.size(); for(int i = 0; i < n; ++i){ if(OnSegment(p, poly[i], poly[(i+1)%n])) return -1; int k = sgn(Cross(poly[(i+1)%n] - poly[i], p - poly[i])); int d1 = sgn(poly[i].y - p.y); int d2 = sgn(poly[(i+1)%n].y - p.y); if(k > 0 && d1 <= 0 && d2 > 0) wn++; if(k < 0 && d2 <= 0 && d1 > 0) wn--; } if(wn != 0) return 1; return 0; } struct Line{//直线定义 Point v, p; Line(Point v, Point p):v(v), p(p) {} Point point(double t){//返回点P = v + (p - v)*t return v + (p - v)*t; } }; struct Circle{ Point c; double r; Circle(Point c, double r):c(c), r(r) {} Point point(double a){//通过圆心角求坐标 return Point(c.x + cos(a)*r, c.y + sin(a)*r); } }; //求圆与直线交点 int getLineCircleIntersection(Line L, Circle C, double& t1, double& t2, vector<Point>& sol){ double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y; double e = a*a + c*c, f = 2*(a*b + c*d), g = b*b + d*d - C.r*C.r; double delta = f*f - 4*e*g;//判别式 if(sgn(delta) < 0)//相离 return 0; if(sgn(delta) == 0){//相切 t1 = -f /(2*e); t2 = -f /(2*e); sol.push_back(L.point(t1));//sol存放交点本身 return 1; } //相交 t1 = (-f - sqrt(delta))/(2*e); sol.push_back(L.point(t1)); t2 = (-f + sqrt(delta))/(2*e); sol.push_back(L.point(t2)); return 2; } //求圆得相交面积 double AreaOfOverlap(Point c1, double r1, Point c2, double r2){ double d = Length(c1 - c2); if(r1 + r2 < d + eps) return 0.0; if(d < fabs(r1 - r2) + eps){ double r = min(r1, r2); return pi*r*r; } double x = (d*d + r1*r1 - r2*r2)/(2.0*d); double p = (r1 + r2 + d)/2.0; double t1 = acos(x/r1); double t2 = acos((d - x)/r2); double s1 = r1*r1*t1; double s2 = r2*r2*t2; double s3 = 2*sqrt(p*(p - r1)*(p - r2)*(p - d)); return s1 + s2 - s3; } bool cmp(Point p1, Point p2) { //极角排序函数 ,角度相同则距离小的在前面 int tmp = sgn(Cross(p1 - lst[0], p2 - lst[0]));//lst为点集 if(tmp > 0) return true; if(tmp == 0 && Dis(lst[0], p1) < Dis(lst[0], p2)) return true; return false; } //点的编号0 ~ n - 1 //返回凸包结果stk[0 ~ top - 1]为凸包的编号 void Graham(int n) { int k = 0; Point p0; p0.x = lst[0].x; p0.y = lst[0].y; for(int i = 1; i < n; ++i) { if( (p0.y > lst[i].y) || ((p0.y == lst[i].y) && (p0.x > lst[i].x)) ) { p0.x = lst[i].x; p0.y = lst[i].y; k = i; } } lst[k] = lst[0]; lst[0] = p0; sort(lst + 1, lst + n, cmp); if(n == 1) { top = 1; stk[0] = 0; return ; } if(n == 2) { top = 2; stk[0] = 0; stk[1] = 1; return ; } stk[0] = 0; stk[1] = 1; top = 2; for(int i = 2; i < n; ++i) { while(top > 1 && Cross(lst[stk[top - 1]] - lst[stk[top - 2]], lst[i] - lst[stk[top - 2]]) <= 0) --top; stk[top] = i; ++top; } return ; } //三点确定外接圆圆心坐标 Point Excenter(Point a, Point b, Point c){ double a1 = b.x - a.x; double b1 = b.y - a.y; double c1 = (a1*a1 + b1*b1)/2; double a2 = c.x - a.x; double b2 = c.y - a.y; double c2 = (a2*a2 + b2*b2)/2; double d = a1*b2 - a2*b1; return Point(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 - a2*c1)/d); } double Dist2(Point p1, Point p2) { //计算距离的平方 double ret = Dot(p1 - p2, p1 - p2); return ret; } double RotatingCalipers(Point* ch, int m) {//返回平面最大距离的平方 if(m == 1) return 0.0; if(m == 2) return Dist2(ch[0], ch[1]); double ret = 0.0; ch[m] = ch[0]; int j = 2; for(int i = 0; i < m; ++i) { while(Cross(ch[i + 1] - ch[i], ch[j] - ch[i]) < Cross(ch[i + 1] - ch[i], ch[j + 1] - ch[i])) j = (j + 1)%m; ret = max(ret, max(Dist2(ch[j], ch[i]), Dist2(ch[j], ch[i + 1]))); } return ret; } int main() { }
#include<bits/stdc++.h>#include<iostream>using namespace std;typedef long long ll;
const double pi = acos(-1.0);const double inf = 1e100;const double eps = 1e-6;struct point{ double x,y;
point(double a = 0, double b = 0) { x=a; y=b; }};point lst[1000];int stk[1000],top=0;int dcmp(double x, double y){ if(fabs(x - y) < eps) return 0; if(x > y) return 1; return -1;}int sgn(double d){ if(fabs(d) < eps) return 0; if(d > 0) return 1; return -1;}typedef point Vector;typedef point Point;point operator +(point a,point b){ point temp; temp.x=a.x+b.x; temp.y=a.y+b.y; return temp;}point operator -(point a,point b){ point temp; temp.x=a.x-b.x; temp.y=a.y-b.y; return temp;}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 Dot(point a,point b){ return a.x*b.x+a.y*b.y;}//叉积double Cross(point a,point b){ return a.x*b.y-a.y*b.x;}//返回向量长度double Length(Vector a){ return sqrt(Dot(a,a));}double Dis(Point p1, Point p2) { //计算 p1p2的 距离 return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));}//返回向量夹角double Angle(Vector a,Vector b){ return asin(Cross(a,b)/Length(a)/Length(b));}//判断是否左转bool ToLeftTest(Vector a,Vector b){ return Cross(a,b)>0;//叉积的sinθ角来判断}//求交点 前提 不相互平行point GetlineIntersection(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 DistanceToLine(point P, point A, point B){ Vector v1 = B-A, v2 = P-A; return fabs(Cross(v1, v2)/Length(v1));}//点P在直线AB上的投影点Point GetLineProjection(Point P, Point A, Point B){ Vector v = B-A; return A+v*(Dot(v, P-A)/Dot(v, v));}//点是否在线段上bool OnSegment(Point p, Point a1, Point a2){ return dcmp(Cross(a1-p, a2-p),0) == 0 && dcmp(Dot(a1-p, a2-p),0) < 0;}//允许在端点处相交的线段判断bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2){ double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1); double c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1); //if判断控制是否允许线段在端点处相交,根据需要添加 if(!sgn(c1) || !sgn(c2) || !sgn(c3) || !sgn(c4)){ bool f1 = OnSegment(b1, a1, a2); bool f2 = OnSegment(b2, a1, a2); bool f3 = OnSegment(a1, b1, b2); bool f4 = OnSegment(a2, b1, b2); bool f = (f1|f2|f3|f4); return f; } return (sgn(c1)*sgn(c2) < 0 && sgn(c3)*sgn(c4) < 0);}//求多边形面积double PolygonArea(Point* p, int n){//p为端点集合,n为端点个数 double s = 0; for(int i = 1; i < n-1; ++i) s += Cross(p[i]-p[0], p[i+1]-p[0]); return s;}//判断点是否在多边形内,若点在多边形内返回1,在多边形外部返回0,在多边形上返回-1int isPointInPolygon(Point p, vector<Point> poly){ int wn = 0; int n = poly.size(); for(int i = 0; i < n; ++i){ if(OnSegment(p, poly[i], poly[(i+1)%n])) return -1; int k = sgn(Cross(poly[(i+1)%n] - poly[i], p - poly[i])); int d1 = sgn(poly[i].y - p.y); int d2 = sgn(poly[(i+1)%n].y - p.y); if(k > 0 && d1 <= 0 && d2 > 0) wn++; if(k < 0 && d2 <= 0 && d1 > 0) wn--; } if(wn != 0) return 1; return 0;}struct Line{//直线定义 Point v, p; Line(Point v, Point p):v(v), p(p) {} Point point(double t){//返回点P = v + (p - v)*t return v + (p - v)*t; }};struct Circle{ Point c; double r; Circle(Point c, double r):c(c), r(r) {} Point point(double a){//通过圆心角求坐标 return Point(c.x + cos(a)*r, c.y + sin(a)*r); }};//求圆与直线交点int getLineCircleIntersection(Line L, Circle C, double& t1, double& t2, vector<Point>& sol){ double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y; double e = a*a + c*c, f = 2*(a*b + c*d), g = b*b + d*d - C.r*C.r; double delta = f*f - 4*e*g;//判别式 if(sgn(delta) < 0)//相离 return 0; if(sgn(delta) == 0){//相切 t1 = -f /(2*e); t2 = -f /(2*e); sol.push_back(L.point(t1));//sol存放交点本身 return 1; } //相交 t1 = (-f - sqrt(delta))/(2*e); sol.push_back(L.point(t1)); t2 = (-f + sqrt(delta))/(2*e); sol.push_back(L.point(t2)); return 2;}//求圆得相交面积double AreaOfOverlap(Point c1, double r1, Point c2, double r2){ double d = Length(c1 - c2); if(r1 + r2 < d + eps) return 0.0; if(d < fabs(r1 - r2) + eps){ double r = min(r1, r2); return pi*r*r; } double x = (d*d + r1*r1 - r2*r2)/(2.0*d); double p = (r1 + r2 + d)/2.0; double t1 = acos(x/r1); double t2 = acos((d - x)/r2); double s1 = r1*r1*t1; double s2 = r2*r2*t2; double s3 = 2*sqrt(p*(p - r1)*(p - r2)*(p - d)); return s1 + s2 - s3;}bool cmp(Point p1, Point p2) { //极角排序函数 ,角度相同则距离小的在前面 int tmp = sgn(Cross(p1 - lst[0], p2 - lst[0]));//lst为点集 if(tmp > 0) return true; if(tmp == 0 && Dis(lst[0], p1) < Dis(lst[0], p2)) return true; return false;}//点的编号0 ~ n - 1//返回凸包结果stk[0 ~ top - 1]为凸包的编号void Graham(int n) { int k = 0; Point p0; p0.x = lst[0].x; p0.y = lst[0].y; for(int i = 1; i < n; ++i) { if( (p0.y > lst[i].y) || ((p0.y == lst[i].y) && (p0.x > lst[i].x)) ) { p0.x = lst[i].x; p0.y = lst[i].y; k = i; } } lst[k] = lst[0]; lst[0] = p0; sort(lst + 1, lst + n, cmp); if(n == 1) { top = 1; stk[0] = 0; return ; } if(n == 2) { top = 2; stk[0] = 0; stk[1] = 1; return ; } stk[0] = 0; stk[1] = 1; top = 2; for(int i = 2; i < n; ++i) { while(top > 1 && Cross(lst[stk[top - 1]] - lst[stk[top - 2]], lst[i] - lst[stk[top - 2]]) <= 0) --top; stk[top] = i; ++top; } return ;}//三点确定外接圆圆心坐标Point Excenter(Point a, Point b, Point c){ double a1 = b.x - a.x; double b1 = b.y - a.y; double c1 = (a1*a1 + b1*b1)/2; double a2 = c.x - a.x; double b2 = c.y - a.y; double c2 = (a2*a2 + b2*b2)/2; double d = a1*b2 - a2*b1; return Point(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 - a2*c1)/d);}double Dist2(Point p1, Point p2) { //计算距离的平方 double ret = Dot(p1 - p2, p1 - p2); return ret;}double RotatingCalipers(Point* ch, int m) {//返回平面最大距离的平方 if(m == 1) return 0.0; if(m == 2) return Dist2(ch[0], ch[1]); double ret = 0.0; ch[m] = ch[0]; int j = 2; for(int i = 0; i < m; ++i) { while(Cross(ch[i + 1] - ch[i], ch[j] - ch[i]) < Cross(ch[i + 1] - ch[i], ch[j + 1] - ch[i])) j = (j + 1)%m; ret = max(ret, max(Dist2(ch[j], ch[i]), Dist2(ch[j], ch[i + 1]))); } return ret;}int main(){
}