1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| const double eps = 1e-5; const double pi = acos(-1.0);
inline int dcmp(double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } inline int zero(double x) { return fabs(x) < eps; }
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 - (Point a, Point 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); } bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; }
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; } double length(Vector a) { return sqrt(a.x * a.x + a.y * a.y); } double distance(Point a, Point b) { return length(b - a); } 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 xmult(Point a, Point b, Point c) { return cross(b - a, c - a); } double area2(Vector a, Vector b, Vector c) { return cross(b - a, c - a); }
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); } Vector getNormal(Vector a) { return Vector(-a.y, a.x); }
struct Line { Point p; Vector v; Line(Point a, Point b) : p(a), v(b - a) {} };
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 getDistanceToLine(Point p, Point a, Point b) { Vector v1 = b - a, v2 = p - a; return fabs(cross(v1, v2)) / length(v1); } double getDistanceToSegment(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 fabs(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 a1, Point b1, Point a2, Point b2) { double c1 = cross(b1 - a1, a2 - a1), c2 = cross(b1 - a1, b2 - a1); double c3 = cross(b2 - a2, a1 - a2), c4 = cross(b2 - a2, b1 - a2); return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0; } bool onSegment(Point p, Point a1, Point a2) { return dcmp(cross(a1 - p, a2 - p)) == 0 && dcmp(dot(a1 - p, a2 - p)) < 0; }
bool onLine(Point p, Vector v, Point a) {return dcmp(cross(v, p - a)) == 0;}
double getPosOnLine(Vector v, Vector t) { if (dcmp(v.x) == 0) return t.y / v.y; return t.x / v.x; }
int getLineCircleIntersection(Point p, Vector v, Point o, double r, double &t1, double &t2) { double a = v.x, b = p.x - o.x, c = v.y, d = p.y - o.y; double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - r * r; double delta = f * f - 4 * e * g; if (dcmp(delta) < 0) return 0; if (dcmp(delta) == 0){ t1 = t2 = -f / (2 * e); return 1; } t1 = (-f - sqrt(delta)) / (2 * e); t2 = (-f + sqrt(delta)) / (2 * e); return 2; }
double polygonArea(Point* p, int n) { double area = 0; for (int i = 1; i < n - 1; i++) area += cross(p[i] - p[0], p[i + 1] - p[0]); return area / 2; }
|