#include #include #include #include #include #include #include using namespace std; /** ==== GEOMETRY NOTEBOOK ========================================================================================== */ const double EPS = 1e-12; template inline char sign(T x) { return abs(x) < EPS ? 0 : x > 0 ? 1 : -1; } template struct Point { T x, y; Point() : x(), y() {} Point(T x, T y) : x(x), y(y) {} template Point(Point p) : x(p.x), y(p.y) {} // basic operators template Point operator+(Point const& p) const { return Point(x + p.x, y + p.y); } template Point operator-(Point const& p) const { return Point(x - p.x, y - p.y); } template Point operator*(Tp&& p) const { return Point{x * p, y * p}; } template Point operator/(Tp&& p) const { return Point{x / p, y / p}; } template Point operator%(Tp&& p) const { return Point{x % p, y % p}; } template Point& operator+=(Point const& p) { return (*this) = (*this) + p; } template Point& operator-=(Point const& p) { return (*this) = (*this) - p; } template Point& operator*=(Tp&& p) { return (*this) = (*this) * p; } template Point& operator/=(Tp&& p) { return (*this) = (*this) / p; } template Point& operator%=(Tp&& p) { return (*this) = (*this) % p; } template bool operator<(Point const& p) const { return x == p.x ? y < p.y : x < p.x; } template bool operator==(Point const& p) const { return x == p.x && y == p.y; } inline T len2() const { return x * x + y * y; } inline double len() const { return hypot(x, y); } template inline T dist2(Point const& p) const { return (*this - p).len2(); } template inline double dist(Point const& p) const { return hypot(x - p.x, y - p.y); } template inline T dot(Point const& p) const { return x * p.x + y * p.y; } // |u| * |v| * cos(alpha) template inline T cross(Point const& p) const { return x * p.y - y * p.x; } // |u| * |v| * sin(alpha) template inline T dot(Point const& a, Point const& b) const { return (a - *this).dot(b - *this); } template inline T cross(Point const& a, Point const& b) const { return (a - *this).cross(b - *this); } /** Orientation of (*this) according to segment AB. 0: collinear, 1: right, -1: left */ inline char orientation(Point const& a, Point const& b) const { return sign((*this - b).cross(b - a)); } /** Orthogonal projection of vector (*this) on vector u. * The point of projection of AB on AC will be at A + AC * AB.proj(AC). */ inline double proj(Point const& u) const { return static_cast(u.dot(*this)) / u.len2(); } /** Distance from (*this) to segment AB */ inline double dist_to_segment(Point const& a, Point const& b) const { Point p = *this; if (a.dist2(b) <= EPS) return p.dist(a); Point ap = p - a, ab = b - a; // if projection doesnt lie on segment, the minimum distance will be to A or B double u = clamp(ap.proj(ab), 0., 1.); Point c = ab * u + a; return p.dist(c); } /** Checks whether point (*this) is in segment AB */ inline bool in_segment(Point const& a, Point const& b) const { Point AB = b - a, AP = (*this) - a; return sign(AB.cross(AP)) == 0 && AB.dot(AP) >= 0 && AB.dot(AP) <= AB.len2(); } /** Rotate current vector rotated counter-clockwise by alpha (in radians) */ inline Point rotate(double alpha) { Point ans; ans.x = cos(alpha) * x - sin(alpha) * y; ans.y = sin(alpha) * x + cos(alpha) * y; return ans; } /** Returns resized version of current vector with length len */ inline Point resize(double len) { Point ans = *this; ans /= ans.len(); ans *= len; return ans; } }; template istream& operator>>(istream& in, Point& p) { return in >> p.x >> p.y; } template ostream& operator<<(ostream& out, Point& p) { return out << p.x << ' ' << p.y; }