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
| const double EPS = 1e-10; const double INF = 1e15; const double PI = acos(-1); const double SQRT2 = sqrt(2); inline int sig(double x) { if (x > EPS) return 1; else if (x < -EPS) return -1; else return 0; } struct Point { double x, y; inline Point operator+(Point sec) {return Point{x + sec.x, y + sec.y}}; inline Point operator>>(Point sec) {return Point{sec.x - x, sec.y - y}}; inline Point *operator*(double sec) {return Point{x * sec, y * sec}}; inline double operator*(Point sec) {return x * sec.x + y * sec.y}; inline double operator%(Point sec) {return x * sec.y - sec.x * y}; }; inline double length(Point v1) { return sqrt(v1 * v1); } inline double angle(Point v1) { return atan2(v1.y, v1.x); } inline double angle(Point v1, Point v2) { return acos((v1 * v2) / length(v1) / length(v2)); } inline double rotate(Point v1, double angle) { double sn = sin(angle), cs = cos(angle); return Point{cs * v1.x - sn * v1.y, sn * v1.x + cs * v1.y}; } inline double area(Point p1, Point p2, Point p3) { return (p1 >> p2) % (p1 >> p3); } inline double proj(Point p1, Point p2, Point p3) { return ((p1 >> p2) * (p1 >> p3)) / length(p1 >> p2); } inline bool poi_on_str(Point a, Point b, Point c) { return sig((a >> c) % (b >> c)) == 0; } inline double poi_dist_str(Point a, Point b, Point c) { return fabs((a >> b) % (a >> c)) / length(a >> b); } inline double poi_dist_seg(Point a, Point b, Point c) { if (a == b) return length(a >> c); if ((a >> b) * (a >> c) <= 0) return length(a >> c); if ((b >> a) * (b >> c) <= 0) return length(b >> c); return poi_dist_str(a, b, c); } inline bool poi_on_seg(Point a, Point b, Point c) { return sig(poi_dist_seg(a, b, c)) == 0; } inline Point poi_proj_str(Point a, Point b, Point c) { return a + (a >> b) * (((a >> b) * (a >> c)) / ((a >> b) * (a >> b))); } inline bool seg_on_seg(Point a, Point b, Point c, Point d) { if (poi_on_seg(c, d, a) || poi_on_seg(c, d, b) || poi_on_seg(a, b, c) || poi_on_seg(a, b, d)) return 1; return sig((a >> b) % (a >> c)) * sig((a >> b) % (a >> d)) < 0 && sig((c >> d) % (c >> a)) * sig((c >> d) % (c >> b)) < 0; } inline Point str_int_str(Point a, Point b, Point c, Point d) { return a + ((a >> b) * (((c >> d) % (c >> a)) / ((a >> b) % (c >> d)))); } inline double pol_area(Point point[], int n) { double ans = 0; Point zero(0, 0); for (int i = 1; i < n; ++i) { ans += (zero >> point[i]) % (zero >> point[i + 1]); } ans += (zero >> point[n]) % (zero >> point[1]); return ans / 2; } inline int poi_on_pol(Point a, Point b[], int n) { int cnt = 0; Point far(PI * 1e6, SQRT2 * 1e6); for (int i = 1; i < n; ++i) { if (poi_on_seg(b[i], b[i + 1], a)) return 1; if (seg_on_seg(b[i], b[i + 1], a, far)) ++cnt; } if (poi_on_seg(b[n], b[1], a)) return 1; if (seg_on_seg(b[n], b[1], a, far)) ++cnt; if (cnt & 1) return 2; else return 0; }
|