计算几何模板啦啦啦啦
来源:互联网 发布:数控折弯机编程操作 编辑:程序博客网 时间:2024/05/17 17:42
计算几何模板啦啦啦
别的不多说.. 给出计算几何模板..
(这个模板大多数都是从刘汝佳《算法竞赛入门经典》中摘录的..)
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <queue>#include <complex>#include <deque>using namespace std;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 ); }//精度const double eps = 1e-10;double _max ( double x, double y ){ return x > y ? x : y; }double _min ( double x, double y ){ return x < y ? x : y; }double _abs ( double x ){ return x < 0 ? -x : x; }int zero ( double x ){ return _abs (x) < eps ? 1 : 0; }int dcmp ( double x ){ if ( zero (x) == 1 ) return 0; return x < 0 ? -1 : 1;}bool operator == ( const Point &a, const Point &b ){ return zero (a.x-b.x) && zero (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 ( Dot ( A, A ) ); }//acos返回余弦弧度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 ); }//rad是弧度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 );}//求直线P+tv和Q+tw的交点(参数式)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;}//求p1、p2构成的直线和p3、p4构成的直线的交点(两点式)Point GetLineIntersectionB ( Point p1, Point p2, Point p3, Point p4 ){ double a1, b1, c1, a2, b2, c2; a1 = p1.y-p2.y; b1 = p2.x-p1.x; c1 = p1.x*p2.y-p1.y*p2.x; a2 = p3.y-p4.y; b2 = p4.x-p3.x; c2 = p3.x*p4.y-p3.y*p4.x; return Point ( (c1*b2-c2*b1)/(a2*b1-a1*b2), (c2*a1-c1*a2)/(a2*b1-a1*b2) );}//求点到直线的距离double DistanceToLine ( Point P, Point A, Point B ){ Vector v1 = B-A, v2 = P-A; return _abs ( Cross ( v1, v2 ) ) / Length (v1);}//求点到线段的距离double DistanceToSegment ( 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 (v2); else if ( dcmp ( Dot ( v1, v3 ) ) > 0 ) return Length (v3); else return _abs ( Cross ( v1, v2 ) ) / Length (v1);}//求点在直线上的投影Point GetLineProjection ( Point P, Point A, Point B ){ Vector v = B-A; return A+v*( Dot ( v, P-A ) / Dot ( v, v ) );}//判断线段相交(规范相交)bool SegmentProperIntersection ( Point p1, Point p2, Point p3, Point p4 ){ if ( Cross ( p1-p3, p2-p3 ) * Cross ( p1-p4, p2-p4 ) < 0 && Cross ( p3-p1, p4-p1 ) * Cross ( p3-p2, p4-p2 ) < 0 ) return true; return false;}//判断线段相交(非规范相交)bool SegmentImproperIntersection ( Point p1, Point p2, Point p3, Point p4 ){ //正常相交 if ( Cross ( p1-p3, p2-p3 ) * Cross ( p1-p4, p2-p4 ) < 0 && Cross ( p3-p1, p4-p1 ) * Cross ( p3-p2, p4-p2 ) < 0 ) return true; //p1在y上 if ( Cross ( p3-p1, p4-p1 ) == 0 && _min(p3.x,p4.x) <= p1.x && p1.x <= _max(p3.x,p4.x) && _min(p3.y,p4.y) <= p1.y && p1.y <= _max(p3.y,p4.y) ) return true; //p2在y上 if ( Cross ( p3-p2, p4-p2 ) == 0 && _min(p3.x,p4.x) <= p2.x && p2.x <= _max(p3.x,p4.x) && _min(p3.y,p4.y) <= p2.y && p2.y <= _max(p3.y,p4.y) ) return true; //p3在x上 if ( Cross ( p1-p3, p2-p3 ) == 0 && _min(p1.x,p2.x) <= p3.x && p3.x <= _max(p1.x,p2.x) && _min(p1.y,p2.y) <= p3.y && p3.y <= _max(p1.y,p2.y) ) return true; //p4在x上 if ( Cross ( p1-p4, p2-p4 ) == 0 && _min(p1.x,p2.x) <= p4.x && p4.x <= _max(p1.x,p2.x) && _min(p1.y,p2.y) <= p4.y && p4.y <= _max(p1.y,p2.y) ) return true; return false;}//多边形的有向面积double PolygonArea ( Point *p, int n ){ double area = 0.0; for ( int i = 2; i < n; i ++ ){ area += Cross ( p[i]-p[1], p[i+1]-p[1] ); } return area/2.0;}struct Circle { Point c; double r; Circle ( Point c=0, double r=0 ) : c(c), r(r) {} Point point ( double a ){ //知道极角求圆上坐标 return Point ( c.x+cos(a)*r, c.y+sin(a)*r ); }};struct Line { Point p1, p2;};vector <Point> sol;//求直线和圆的交点,返回交点的个数int GetLineCircleIntersection ( Line L, Circle C ){ Point p, p1, p2; p = GetLineProjection ( C.c, L.p1, L.p2 ); double dis = Length ( C.c-p ); if ( zero(dis-C.r) == 1 ){ sol.push_back (p); return 1; } if ( dis > C.r ) return 0; Vector v = (L.p2-L.p1) / Length (L.p2-L.p1); double t = sqrt ( C.r*C.r - dis*dis ); p1 = p+v*t; p2 = p-v*t; sol.push_back (p1); sol.push_back (p2); return 2;}//求极角double angle ( Vector v ){ return atan2 ( v.y, v.x ); }//两圆相交,返回交点个数int GetCircleCircleIntersection ( Circle C1, Circle C2 ){ double d = Length (C1.c-C2.c); if ( dcmp (d) == 0 ){ if ( dcmp (C1.r-C2.r) == 0 ) return -1; //两圆重合 return 0; } if ( dcmp (C1.r+C2.r-d) < 0 ) return 0; if ( dcmp ( _abs (C1.r-C2.r)-d ) > 0 ) return 0; double a = angle (C2.c-C1.c); double da = acos ( (C1.r*C1.r+d*d-C2.r*C2.r) / (2*C1.r*d) ); Point p1 = C1.point (a-da), p2 = C1.point (a+da); sol.push_back (p1); if ( p1 == p2 ) return 1; sol.push_back (p2); return 2;}const double PI = acos (-1);Vector v[2];//过p作圆C的切线int GetTarget ( Point p, Circle C ){ Vector u = C.c - p; double dis = Length (u); if ( dis < C.r ) return 0; else if ( dcmp (dis-C.r) == 0 ){ v[0] = Rotate ( u, PI/2 ); return 1; } else { double ang = asin (C.r/dis); v[0] = Rotate ( u, -ang ); v[1] = Rotate ( u, +ang ); return 2; }}//求两圆的公切线Point a[10], b[10];int GetTangents ( Circle A, Circle B ){ int cnt = 0; if ( A.r < B.r ){ swap ( A, B ); swap ( a, b ); } double d2 = (A.c.x-B.c.x)*(A.c.x-B.c.x) + (A.c.y-B.c.y)*(A.c.y-B.c.y); double rdiff = A.r-B.r; double rsum = A.r+B.r; if ( d2 < rdiff*rdiff ) return 0; double base = atan2 ( B.c.y-A.c.y, B.c.x-A.c.x ); if ( zero (d2) && A.r == B.r ) return -1; if ( zero ( rdiff*rdiff-d2 ) ){ cnt ++; a[cnt] = A.point (base); b[cnt] = B.point (base); return 1; } double ang = acos ((A.r-B.r)/sqrt(d2)); cnt ++; a[cnt] = A.point (base+ang); b[cnt] = B.point (base+ang); cnt ++; a[cnt] = A.point (base-ang); b[cnt] = B.point (base-ang); if ( zero ( rsum*rsum-d2 ) ){ cnt ++; a[cnt] = A.point (base); b[cnt] = B.point (PI+base); } else if ( d2 > rsum*rsum ){ double ang = acos ((A.r+B.r)/sqrt(d2)); cnt ++; a[cnt] = A.point (base+ang); b[cnt] = B.point (PI+base+ang); cnt ++; a[cnt] = A.point (base-ang); b[cnt] = B.point (PI+base-ang); } return cnt;}int main (){ return 0;}
0 0
- 计算几何模板啦啦啦啦
- [模板]计算几何模板
- 经典计算几何模板
- 计算几何模板2
- 计算几何 模板
- 计算几何模板
- 计算几何经典模板
- 计算几何模板
- ACM计算几何模板
- 计算几何模板
- 计算几何模板
- 计算几何模板
- 计算几何 模板
- 计算几何初步模板
- 计算几何三维模板
- 二维计算几何模板
- 计算几何模板
- 计算几何模板
- 1.关系性数据库及SQL
- Java中堆内存和栈内存详解
- hdu1757 A Simple Math Problem(矩阵快速幂)
- Image-Loader
- 揭开A F N e t w o r k i n g 框 架 的神秘面纱 (上)
- 计算几何模板啦啦啦啦
- 查Oracle的隐藏参数---创建视图v$parameter
- 使用 VisualVM 进行性能分析及调优
- 2016.04.10培训日记
- 控制台Console中处理窗口Form消息
- 汉诺塔VI
- 【Extjs学习笔记01】使用Sencha Cmd构建项目
- cf 558C C. Amr and Chemistry (51nod 1483)
- 2016.04.17培训日记