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
| const double EPS = 1e-9; const double PI = acos(-1.0);
inline bool eq(double a, double b) { return fabs(a - b) < EPS; }
struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); } Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); } Point operator*(double k) const { return Point(x * k, y * k); } Point operator/(double k) const { return Point(x / k, y / k); } bool operator==(const Point& p) const { return eq(x, p.x) && eq(y, p.y); } double dot(const Point& p) const { return x * p.x + y * p.y; } double cross(const Point& p) const { return x * p.y - y * p.x; } double norm() const { return sqrt(x * x + y * y); } double norm2() const { return x * x + y * y; } Point unit() const { return *this / norm(); } Point rotate(double theta) const { return Point(x * cos(theta) - y * sin(theta), x * sin(theta) + y * cos(theta)); } };
bool on_segment(Point p, Point a, Point b) { return (p - a).cross(p - b) == 0 && (p - a).dot(p - b) <= 0; }
bool segments_intersect(Point a1, Point a2, Point b1, Point b2) { auto cross = [](Point p1, Point p2, Point p3) { return (p2 - p1).cross(p3 - p1); }; double c1 = cross(a1, a2, b1); double c2 = cross(a1, a2, b2); double c3 = cross(b1, b2, a1); double c4 = cross(b1, b2, a2); if (c1 * c2 < 0 && c3 * c4 < 0) return true; if (c1 == 0 && on_segment(b1, a1, a2)) return true; if (c2 == 0 && on_segment(b2, a1, a2)) return true; if (c3 == 0 && on_segment(a1, b1, b2)) return true; if (c4 == 0 && on_segment(a2, b1, b2)) return true; return false; }
double polygon_area(const vector<Point>& poly) { double area = 0; int n = poly.size(); for (int i = 0; i < n; i++) { area += poly[i].cross(poly[(i + 1) % n]); } return fabs(area) / 2.0; }
bool point_in_polygon(Point p, const vector<Point>& poly) { int n = poly.size(); int cnt = 0; for (int i = 0; i < n; i++) { Point a = poly[i], b = poly[(i + 1) % n]; if (on_segment(p, a, b)) return true; if (a.y > b.y) swap(a, b); if (p.y <= a.y || p.y > b.y) continue; if ((b - a).cross(p - a) > 0) cnt++; } return cnt % 2 == 1; }
|