• 几何模板总结——算法竞赛入门经典(第二版)


      1 #include <iostream>
      2 #include <string>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cmath>
      6 #include <vector>
      7 #include <algorithm>
      8 
      9 using namespace std;
     10 
     11 const double PI = acos(-1);
     12 
     13 struct Point {
     14     double x, y;
     15     Point(double x = 0, double y = 0) : x(x), y(y) {}
     16 };
     17 
     18 typedef Point Vector;
     19 Vector operator + (const Vector &A, const Vector &B) { return Vector(A.x + B.x, A.y + B.y); }
     20 Vector operator - (const Point &A, const Point &B) { return Vector(A.x - B.x, A.y - B.y); }
     21 Vector operator * (const Vector &A, const double &p) { return Vector(A.x * p, A.y * p); }
     22 Vector operator / (const Vector &A, const double &p) { return Vector(A.x / p, A.y / p); }
     23 bool operator < (const Point &a, const Point &b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
     24 
     25 const double eps = 1e-10;
     26 int dcmp(double x) {
     27     if(fabs(x) < eps) return 0;
     28     else return x < 0 ? -1 : 1;
     29 }
     30 
     31 bool operator == (const Point &a, const Point &b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; }
     32 
     33 double Dot(const Vector &A, const Vector &B) { return A.x * B.x + A.y * B.y; }
     34 double Length(const Vector &A) { return sqrt(Dot(A, A)); }
     35 double Angle(const Vector &A, const Vector &B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
     36 
     37 double Cross(const Vector &A, const Vector B) { return A.x * B.y - A.y * B.x; }
     38 double Area2(const Point &A, const Point &B, const Point &C) { return Cross(B - A, C - A); }
     39 
     40 Vector Rotate(const Vector &A, double rad) { return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); }
     41 
     42 Vector Normal(const Vector &A) {
     43     double L = Length(A);
     44     return Vector(-A.y / L, A.x / L);
     45 }
     46 
     47 Point GetLineIntersection(const Point &P, const Vector &v, const Point &Q, const Vector &w) {
     48     Vector u = P - Q;
     49     double t = Cross(w, u) / Cross(v, w);
     50     return P + v * t;
     51 }
     52 
     53 double DistanceToLine(const Point &P, const Point &A, const Point &B) {
     54     Vector v1 = B - A, v2 = P - A;
     55     return fabs(Cross(v1, v2)) / Length(v1);
     56 }
     57 double DistanceToLine_(const Point &P, const Point &A, const Point &B) {
     58     Vector v1 = B - A, v2 = P - A;
     59     return Cross(v1, v2) / Length(v1);
     60 }
     61 double DistanceToSegment(const Point &P, const Point &A, const Point &B) {
     62     if(A == B) return Length(P - A);
     63     Vector v1 = B - A, v2 = P - A, v3 = P - B;
     64     if(dcmp(Dot(v1, v2)) < 0) return Length(v2);
     65     else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);
     66     else return fabs(Cross(v1, v2)) / Length(v1);
     67 }
     68 
     69 Point GetLineProjection(const Point &P, const Point &A, const Point &B) {
     70     Vector v = B - A;
     71     return A + v * (Dot(v, P - A) / Dot(v, v));
     72 }
     73 
     74 bool SegmentProperIntersection(const Point &a1, const Point &a2, const Point &b1, const Point &b2) {
     75     double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1), c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
     76     return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
     77 }
     78 
     79 bool OnSegment(const Point &p, const Point &a1, const Point &a2) {
     80     return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
     81 }
     82 
     83 double ConvexPolygonArea(Point *p, int n) {
     84     double area = 0;
     85     for(int i = 1; i < n - 1; ++i) area += Cross(p[i] - p[0], p[i + 1] - p[0]);
     86     return area / 2;
     87 }
     88 
     89 double PolygonArea(Point *p, int n) {
     90     double area = 0;
     91 
     92     for(int i = 1; i < n - 1; ++i) area += Cross(p[i] - p[0], p[i + 1] - p[0]);
     93     return area / 2;
     94 }
     95 
     96 struct Line {
     97   Point p;
     98   Vector v;
     99   Line(Point p, Vector v):p(p),v(v) { }
    100   Point point(double t) {
    101     return p + v*t;
    102   }
    103   Line move(double d) {
    104     return Line(p + Normal(v)*d, v);
    105   }
    106 };
    107 
    108 Line getLine(double x1, double y1, double x2, double y2) {
    109   Point p1(x1,y1);
    110   Point p2(x2,y2);
    111   return Line(p1, p2-p1);
    112 }
    113 
    114 struct Circle {
    115     Point c;
    116     double r;
    117 
    118     Circle(Point c, double r) : c(c), r(r) {}
    119 
    120     Point point(const double &a) const {
    121         return Point(c.x + cos(a) * r, c.y + sin(a) * r);
    122     }
    123 };
    124 
    125 int getLineCircleIntersection(Line L, Circle C, double &t1, double &t2, vector<Point> &sol) {
    126     double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
    127     double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
    128     double delta = f * f - 4 * e * g;
    129     if(dcmp(delta) < 0) return 0;
    130     if(dcmp(delta) == 0) {
    131         t1 = t2 = -f / (2 * e);
    132         sol.push_back(L.point(t1));
    133         return 1;
    134     }
    135     t1 = (-f - sqrt(delta)) / (2 * e);
    136     sol.push_back(L.point(t1));
    137     t2 = (-f + sqrt(delta)) / (2 * e);
    138     sol.push_back(L.point(t2));
    139     return 2;
    140 }
    141 
    142 double angle(const Vector &v) { return atan2(v.y, v.x); }
    143 
    144 int getCircleCircleIntersection(Circle C1, Circle C2, vector<Point> &sol) {
    145     double d = Length(C1.c - C2.c);
    146     if(dcmp(d) == 0) {
    147         if(dcmp(C1.r - C2.r) == 0) return -1;
    148         return 0;
    149     }
    150     if(dcmp(C1.r + C2.r - d) < 0) return 0;
    151     if(dcmp(fabs(C1.r - C2.r) - d) > 0) return 0;
    152 
    153     double a = angle(C2.c - C1.c);
    154     double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d));
    155 
    156     Point p1 = C1.point(a - da), p2 = C1.point(a + da);
    157 
    158     sol.push_back(p1);
    159     if(p1 == p2) return 1;
    160     sol.push_back(p2);
    161     return 2;
    162 }
    163 
    164 int getTangents(Point p, Circle C, Vector *v) {
    165     Vector u = C.c - p;
    166     double dist = Length(u);
    167     if(dist < C.r) return 0;
    168     else if(dcmp(dist - C.r) == 0) {
    169 //        v[0] = Rotate(u, PI / 2);
    170         return 1;
    171     }
    172     else {
    173         double ang = asin(C.r / dist);
    174         v[0] = Rotate(u, -ang);
    175         v[1] = Rotate(u, +ang);
    176         return 2;
    177     }
    178 }
    179 
    180 int getTangents(Circle A, Circle B, Point *a, Point *b) {
    181     int cnt = 0;
    182     if(A.r < B.r) { swap(A, B); swap(a, b); }
    183     int 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);
    184     int rdiff = A.r - B.r;
    185     int rsum = A.r + B.r;
    186     if(d2 < rdiff * rdiff) return 0;
    187 
    188     double base = atan2(B.c.y - A.c.y, B.c.x - A.c.x);
    189     if(d2 == 0 && A.r == B.r) return -1;
    190     if(d2 == rdiff * rdiff) {
    191         a[cnt] = A.point(base);
    192         b[cnt] = B.point(base);
    193         ++cnt;
    194         return 1;
    195     }
    196     double ang = acos((A.r - B.r) / sqrt(d2));
    197     a[cnt] = A.point(base + ang);
    198     b[cnt] = B.point(base + ang);
    199     ++cnt;
    200     a[cnt] = A.point(base - ang);
    201     b[cnt] = B.point(base - ang);
    202     ++cnt;
    203     if(d2 == rsum * rsum) {
    204         a[cnt] = A.point(base);
    205         b[cnt] = B.point(PI + base);
    206         ++cnt;
    207     }
    208     else if(d2 > rsum * rsum) {
    209         double ang = acos((A.r + B.r) / sqrt(d2));
    210         a[cnt] = A.point(base + ang);
    211         b[cnt] = B.point(PI + base + ang);
    212         ++cnt;
    213         a[cnt] = A.point(base - ang);
    214         b[cnt] = B.point(PI + base - ang);
    215         ++cnt;
    216     }
    217     return cnt;
    218 }
    219 
    220 double torad(const double &deg) {
    221     return deg / 180 * PI;
    222 }
    223 
    224 void get_coord(const double &R, double lat, double lng, double &x, double &y, double &z) {
    225     lat = torad(lat);
    226     lng = torad(lng);
    227     x = R * cos(lat) * cos(lng);
    228     y = R * cos(lat) * sin(lng);
    229     z = R * sin(lat);
    230 }
    231 
    232 int ConvexHull(Point *p, int n, Point *ch) {
    233     sort(p, p + n);
    234     int m = 0;
    235     for(int i = 0; i < n; ++i) {
    236         while(m > 1 && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) --m;
    237         ch[m++] = p[i];
    238     }
    239     int k = m;
    240     for(int i = n - 2; i >= 0; --i) {
    241         while(m > k && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0) --m;
    242         ch[m++] = p[i];
    243     }
    244     if(n > 1) --m;
    245     return m;
    246 }
    247 
    248 int  isPointInPolygon(Point p, Point *poly, int n) {
    249     int wn = 0;
    250     for(int i = 0;i < n; ++i) {
    251         if(OnSegment(p, poly[i], poly[(i+1)%n])) return -1;
    252         int k=dcmp(Cross(poly[(i+1)%n]-poly[i], p-poly[i]));
    253         int d1=dcmp(poly[i].y-p.y);
    254         int d2=dcmp(poly[(i+1)%n].y-p.y);
    255         if(k>0&&d1<=0&&d2>0) wn++;
    256         if(k<0&&d2<=0&&d1>0) wn--;
    257     }
    258     if(wn!=0)  return 1;
    259     else return 0;
    260 }
    261 
    262 Point read_point() {
    263     Point P;
    264     scanf("%lf%lf",&P.x,&P.y);
    265     return P;
    266 }
    267 
    268 int main() {
    269 
    270 }
  • 相关阅读:
    Android 如何自定义EditText 下划线?
    一步一步理解 Java 企业级应用的可扩展性
    客户案例—北京优络时代科技有限公司
    11个显著提升 ASP.NET 应用程序性能的技巧——第1部分
    如何用 React Native 创建一个iOS APP?(二)
    如何与 DevOps 为伍?
    通过 DevOps 整合开发和应用安全管道
    性能为王:选择模拟监控的10大理由!
    模拟监控和真实用户体验监测,选哪个?
    PHP 之 Laravel 框架安装及相关开源软件
  • 原文地址:https://www.cnblogs.com/wpnan/p/4043623.html
Copyright © 2020-2023  润新知