Created: 2019-11-09 Sat 13:53
WA
initiallystruct point_i {
int x, y;
point_i() { x = y = 0; }
point_i(int _x, int _y) : x(_x), y(_y) {}
bool operator=(point_i & other) const {
return x == other.x && y == other.y;
}
bool operator<(point_i & other) const {
if (x == other.x)
return y < other.y;
else return x < other.x;
}
};
#include <math.h>
#define EPS 1E-9
struct point {
double x, y;
point() { x = y = 0; }
point(double _x, double _y) : x(_x), y(_y) {}
bool operator=(point & other) const {
return fabs(x - other.x) < EPS && fabs(y - other.y) < EPS;
}
bool operator<(point & other) const {
if (fabs(x - other.x) < EPS)
return y < other.y;
else return x < other.x;
}
};
\[ \sqrt{ (a_x - b_x)^2 + (a_y - b_y)^2} \]
Counter-clockwise rotation by \( \theta \)
\[ \left[ \begin{array}{l} x' \\ y' \end{array} \right] = \left[ \begin{array}{ll} cos(\theta) & -sin(\theta) \\ sin(\theta) & cos(\theta) \end{array} \right] \left[ \begin{array}{l} x \\ y \end{array} \right] \]
double hypot(point &a, point &b) const {
double dx=a.x-b.x;
double dy=a.y-b.y;
return sqrt(dx * dx + dy * dy);
}
point ccw(point &a, double &theta) const {
double st = sin(theta);
double ct = cos(theta);
return point(a.x*ct +a.y*st, a.y* ct - a.x * st);
}
\[ ax + by + c = 0 \]
// From Competitive Programming 3
struct line {
point a, b, c;
};
void pointsToLine(point p1, point p2, line &l) {
if (fabs(p1.x - p2.x) < EPS) {// vertical line
l.a = 1.0; l.b = 0.0; l.c = -p1.x;
} else {
l.a = -(double)(p1.y - p2.y) / (p1.x - p2.x);
l.b = 1.0; // IMPORTANT: we fix the value of b to 1.0
l.c = -(double)(l.a * p1.x) - p1.y;
} }
bool areParallel(line l1, line l2) {
return (fabs(l1.a-l2.a) < EPS) && (fabs(l1.b-l2.b) < EPS);
}
bool areSame(line l1, line l2) {
return areParallel(l1 ,l2) && (fabs(l1.c - l2.c) < EPS);
}
\[ \begin{array}{l} a_1 x + b_1 y + c_1 = 0 \\ a_2 x + b_2 y + c_2 = 0 \\ \end{array} \]
// returns true (+ intersection point) if two lines are intersect
bool areIntersect(line l1, line l2, point &p) {
if (areParallel(l1, l2)) return false; // no intersection
// solve system of 2 linear algebraic equations with 2 unknowns
p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
// special case: test for vertical line to avoid division by zero
if (fabs(l1.b) > EPS) p.y = -(l1.a * p.x + l1.c);
else p.y = -(l2.a * p.x + l2.c);
return true;
}
struct vec {
double x, y;
vec(double _x, double _y) : x(_x), y(_y) {}
};
vec toVec(point a, point b) { // convert 2 points to vector a->b
return vec(b.x - a.x, b.y - a.y);
}
vec scale(vec v, double s) { // nonnegative s = [<1 .. 1 .. >1]
return vec(v.x * s, v.y * s);
}
// shorter.same.longer
point translate(point p, vec v) {// translate p according to v
return point(p.x + v.x , p.y + v.y);
}
double dot(vec a, vec b) {
return (a.x * b.x + a.y * b.y);
}
double norm_sq(vec v) {
return v.x * v.x + v.y * v.y;
}
// returns the distance from p to the line defined by two points a and b
double distToLine(point p, point a, point b, point &c) {
// formula: c = a + u * ab
vec ap = toVec(a, p), ab = toVec(a, b);
double u = dot(ap, ab) / norm_sq(ab);
c = translate(a, scale(ab, u));
return dist(p, c);
}
double distToLineSegment(point p, point a, point b, point &c) {
vec ap = toVec(a, p), ab = toVec(a, b);
double u = dot(ap, ab) / norm_sq(ab);
if (u < 0.0) {
c = point(a.x, a.y); // closer to a
return dist(p, a);
}
// Euclidean distance between p and a
if (u > 1.0) {
c = point(b.x, b.y); // closer to b
return dist(p, b); }
// Otherwise, do the normal thing
c = translate(a, scale(ab, u));
return dist(p, c);
}
double angle(point a, point o, point b) { // returns angle aob in radians
vec oa = toVector(o, a), ob = toVector(o, b);
return acos(dot(oa, ob) / sqrt(norm_sq(oa) * norm_sq(ob)));
}
// returns true if point r is on the left side of line pq
bool ccw(point p, point q, point r) {
return cross(toVec(p, q), toVec(p, r)) > EPS;
}
// returns true if point r is on the same line as the line pq
bool collinear(point p, point q, point r) {
return fabs(cross(toVec(p, q), toVec(p, r))) < EPS;
}