This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub kmyk/competitive-programming-library
typedef complex<double> point;
double cross(point a, point b) { return a.real() * b.imag() - a.imag() * b.real(); }
int ccw(point a, point b, point c) { double z = cross(b - a, c - a); return z > eps ? 1 : z < - eps ? -1 : 0; }
/**
* @brief Andrew's Monotone Chain
*/
vector<point> convex_hull(vector<point> ps) {
int n = ps.size();
sort(ALL(ps), [&](point a, point b) { return make_pair(a.real(), a.imag()) < make_pair(b.real(), b.imag()); });
vector<point> ch(2 * n);
int k = 0;
for (int i = 0; i < n; ch[k ++] = ps[i ++]) // lower-hull
while (k >= 2 and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) -- k;
for (int i = n - 2, t = k + 1; i >= 0; ch[k ++] = ps[i --]) // upper-hull
while (k >= t and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) -- k;
ch.resize(k - 1);
return ch;
}
struct circle { point p; double r; };
struct line { point s, t; };
struct segment { point s, t; };
struct ray { point s, t; };
/**
* @note あまり小さくすると誤差で死ぬ
*/
const double eps = 1e-6;
double sq(double x) { return pow(x, 2); }
struct point { double y, x; };
point operator + (point a, point b) { return (point) { a.y + b.y, a.x + b.x }; }
point operator - (point a, point b) { return (point) { a.y - b.y, a.x - b.x }; }
point operator * (point a, double b) { return (point) { a.y * b, a.x * b }; }
point operator / (point a, double b) { return (point) { a.y / b, a.x / b }; }
point operator < (point a, point b) { return make_pair(a.y, a.x) < make_pair(b.y, b.x); }
double distance(point a, point b) { return sqrt(sq(a.y - b.y) + sq(a.x - b.x)); }
double dot(point a, point b) { return a.x * b.x + a.y * b.y; }
double cross(point a, point b) { return a.x * b.y - a.y * b.x; }
int ccw(point a, point b, point c) { double z = cross(b - a, c - a); return z > eps ? 1 : z < - eps ? -1 : 0; }
/**
* @brief segment - segment, inclusive
*/
bool does_intersect(segment const & a, segment const & b){
return ccw(a.s, a.t, b.s) * ccw(a.s, a.t, b.t) <= 0 and
ccw(b.s, b.t, a.s) * ccw(b.s, b.t, a.t) <= 0;
}
/**
* @brief point and line
*/
bool does_intersect(point a, line b) { return ccw(0, a - b.s, b.t - b.s) == 0; }
bool does_intersect(line a, point b) { return does_intersect(b, a); }
/**
* @brief line and line
*/
bool is_parallel(line a, line b) { return ccw(0, a.t - a.s, b.t - b.s) == 0; }
bool is_same(line a, line b) { return does_intersect(a.s, b) and does_intersect(a.t, b); }
/**
* @note false if two lines are the same
*/
bool does_intersect(line a, line b) {
return not is_parallel(a, b)
and not is_same(a, b);
}
point intersection(line a, line b) {
assert (does_intersect(a, b));
double p = cross(a.t - a.s, b.t - b.s);
double q = cross(a.t - a.s, a.t - b.s);
return (q / p) * (b.t - b.s) + b.s;
}
/**
* @note helper for segments and rays
*/
template <typename T, typename U>
bool does_intersect_linelikes(T const & a, U const & b) {
if (not does_intersect(to_line(a), to_line(b))) return false;
point c = intersection(to_line(a), to_line(b));
return does_intersect(c, a)
and does_intersect(c, b);
}
line to_line(segment a) {
return { a.s, a.t };
}
bool does_intersect(point a, segment b) {
return abs(cross(b.t - b.s, a - b.s)) < eps
and dot(b.t - b.s, a - b.s) > - eps
and dot(b.s - b.t, a - b.t) > - eps;
}
bool does_intersect(segment a, point b) {
return does_intersect(b, a);
}
bool is_overwraped(segment a, segment b) {
return does_intersect(a.s, b)
and does_intersect(a.t, b);
}
bool does_intersect(segment a, segment b) {
return does_intersect_linelikes(a, b);
}
point intersection(segment a, segment b) {
assert (does_intersect(a, b));
return intersection(to_line(a), to_line(b));
}
line to_line(ray a) {
return { a.s, a.t };
}
bool does_intersect(point a, ray b) {
return abs(cross(b.t - b.s, a - b.s)) < eps
and dot(b.t - b.s, a - b.s) > - eps;
}
bool does_intersect(ray a, point b) {
return does_intersect(b, a);
}
bool is_overwraped(ray a, ray b) {
return (does_intersect(a.s, b) and does_intersect(a.t, b))
or (does_intersect(b.s, a) and does_intersect(b.t, a));
}
bool does_intersect(ray a, ray b) {
return does_intersect_linelikes(a, b);
}
point intersection(ray a, ray b) {
assert (does_intersect(a, b));
return intersection(to_line(a), to_line(b));
}
struct polygon { vector<point> ps; };
segment nth_segment(polygon const & a, int i) {
int j = (i+1) % a.ps.size();
return { a.ps[i], a.ps[j] };
}
bool does_intersect(ray a, segment b) { return does_intersect_linelikes(a, b); }
bool does_intersect(segment a, ray b) { return does_intersect_linelikes(a, b); }
point intersection(ray a, segment b) { return intersection_linelikes(a, b); }
point intersection(segment a, ray b) { return intersection_linelikes(a, b); }
template <typename T>
vector<point> intersections_polygon_linelike(polygon const & a, T const & b) {
vector<point> result;
repeat (i, a.ps.size()) {
if (does_intersect(nth_segment(a, i), b)) {
result.push_back(intersection(nth_segment(a, i), b));
}
}
return result;
}
bool does_intersect(polygon const & a, ray const & b) {
return not intersections_polygon_linelike(a, b).empty();
}
bool does_intersect(polygon const & a, point const & b) {
ray c = { b, b + point(1, 0) };
return intersections_polygon_linelike(a, c).size() % 2 == 1;
}
bool does_intersect_strict(polygon const & a, point const & b) {
repeat (i, a.ps.size()) {
if (does_intersect(nth_segment(a, i), b)) {
return false; // when the point is on a segment of the polygon
}
}
return does_intersect(a, b);
}
bool does_intersect_strict(polygon const & a, segment const & b) { // the boundary is not included
vector<point> ps = intersections_polygon_linelike(a, b);
for (point p : ps) {
bool ignored = false;
if (abs(p - b.s) < eps or abs(p - b.t) < eps) {
ignored = true;
}
if (not ignored) {
for (point q : a.ps) {
if (abs(p - q) < eps) {
ignored = true; // when the intersection point is one of the vertex of the polygon
break;
}
}
}
if (not ignored) return true;
}
return false;
}
#line 1 "old/a.inc.cpp"
typedef complex<double> point;
double cross(point a, point b) { return a.real() * b.imag() - a.imag() * b.real(); }
int ccw(point a, point b, point c) { double z = cross(b - a, c - a); return z > eps ? 1 : z < - eps ? -1 : 0; }
/**
* @brief Andrew's Monotone Chain
*/
vector<point> convex_hull(vector<point> ps) {
int n = ps.size();
sort(ALL(ps), [&](point a, point b) { return make_pair(a.real(), a.imag()) < make_pair(b.real(), b.imag()); });
vector<point> ch(2 * n);
int k = 0;
for (int i = 0; i < n; ch[k ++] = ps[i ++]) // lower-hull
while (k >= 2 and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) -- k;
for (int i = n - 2, t = k + 1; i >= 0; ch[k ++] = ps[i --]) // upper-hull
while (k >= t and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) -- k;
ch.resize(k - 1);
return ch;
}
struct circle { point p; double r; };
struct line { point s, t; };
struct segment { point s, t; };
struct ray { point s, t; };
/**
* @note あまり小さくすると誤差で死ぬ
*/
const double eps = 1e-6;
double sq(double x) { return pow(x, 2); }
struct point { double y, x; };
point operator + (point a, point b) { return (point) { a.y + b.y, a.x + b.x }; }
point operator - (point a, point b) { return (point) { a.y - b.y, a.x - b.x }; }
point operator * (point a, double b) { return (point) { a.y * b, a.x * b }; }
point operator / (point a, double b) { return (point) { a.y / b, a.x / b }; }
point operator < (point a, point b) { return make_pair(a.y, a.x) < make_pair(b.y, b.x); }
double distance(point a, point b) { return sqrt(sq(a.y - b.y) + sq(a.x - b.x)); }
double dot(point a, point b) { return a.x * b.x + a.y * b.y; }
double cross(point a, point b) { return a.x * b.y - a.y * b.x; }
int ccw(point a, point b, point c) { double z = cross(b - a, c - a); return z > eps ? 1 : z < - eps ? -1 : 0; }
/**
* @brief segment - segment, inclusive
*/
bool does_intersect(segment const & a, segment const & b){
return ccw(a.s, a.t, b.s) * ccw(a.s, a.t, b.t) <= 0 and
ccw(b.s, b.t, a.s) * ccw(b.s, b.t, a.t) <= 0;
}
/**
* @brief point and line
*/
bool does_intersect(point a, line b) { return ccw(0, a - b.s, b.t - b.s) == 0; }
bool does_intersect(line a, point b) { return does_intersect(b, a); }
/**
* @brief line and line
*/
bool is_parallel(line a, line b) { return ccw(0, a.t - a.s, b.t - b.s) == 0; }
bool is_same(line a, line b) { return does_intersect(a.s, b) and does_intersect(a.t, b); }
/**
* @note false if two lines are the same
*/
bool does_intersect(line a, line b) {
return not is_parallel(a, b)
and not is_same(a, b);
}
point intersection(line a, line b) {
assert (does_intersect(a, b));
double p = cross(a.t - a.s, b.t - b.s);
double q = cross(a.t - a.s, a.t - b.s);
return (q / p) * (b.t - b.s) + b.s;
}
/**
* @note helper for segments and rays
*/
template <typename T, typename U>
bool does_intersect_linelikes(T const & a, U const & b) {
if (not does_intersect(to_line(a), to_line(b))) return false;
point c = intersection(to_line(a), to_line(b));
return does_intersect(c, a)
and does_intersect(c, b);
}
line to_line(segment a) {
return { a.s, a.t };
}
bool does_intersect(point a, segment b) {
return abs(cross(b.t - b.s, a - b.s)) < eps
and dot(b.t - b.s, a - b.s) > - eps
and dot(b.s - b.t, a - b.t) > - eps;
}
bool does_intersect(segment a, point b) {
return does_intersect(b, a);
}
bool is_overwraped(segment a, segment b) {
return does_intersect(a.s, b)
and does_intersect(a.t, b);
}
bool does_intersect(segment a, segment b) {
return does_intersect_linelikes(a, b);
}
point intersection(segment a, segment b) {
assert (does_intersect(a, b));
return intersection(to_line(a), to_line(b));
}
line to_line(ray a) {
return { a.s, a.t };
}
bool does_intersect(point a, ray b) {
return abs(cross(b.t - b.s, a - b.s)) < eps
and dot(b.t - b.s, a - b.s) > - eps;
}
bool does_intersect(ray a, point b) {
return does_intersect(b, a);
}
bool is_overwraped(ray a, ray b) {
return (does_intersect(a.s, b) and does_intersect(a.t, b))
or (does_intersect(b.s, a) and does_intersect(b.t, a));
}
bool does_intersect(ray a, ray b) {
return does_intersect_linelikes(a, b);
}
point intersection(ray a, ray b) {
assert (does_intersect(a, b));
return intersection(to_line(a), to_line(b));
}
struct polygon { vector<point> ps; };
segment nth_segment(polygon const & a, int i) {
int j = (i+1) % a.ps.size();
return { a.ps[i], a.ps[j] };
}
bool does_intersect(ray a, segment b) { return does_intersect_linelikes(a, b); }
bool does_intersect(segment a, ray b) { return does_intersect_linelikes(a, b); }
point intersection(ray a, segment b) { return intersection_linelikes(a, b); }
point intersection(segment a, ray b) { return intersection_linelikes(a, b); }
template <typename T>
vector<point> intersections_polygon_linelike(polygon const & a, T const & b) {
vector<point> result;
repeat (i, a.ps.size()) {
if (does_intersect(nth_segment(a, i), b)) {
result.push_back(intersection(nth_segment(a, i), b));
}
}
return result;
}
bool does_intersect(polygon const & a, ray const & b) {
return not intersections_polygon_linelike(a, b).empty();
}
bool does_intersect(polygon const & a, point const & b) {
ray c = { b, b + point(1, 0) };
return intersections_polygon_linelike(a, c).size() % 2 == 1;
}
bool does_intersect_strict(polygon const & a, point const & b) {
repeat (i, a.ps.size()) {
if (does_intersect(nth_segment(a, i), b)) {
return false; // when the point is on a segment of the polygon
}
}
return does_intersect(a, b);
}
bool does_intersect_strict(polygon const & a, segment const & b) { // the boundary is not included
vector<point> ps = intersections_polygon_linelike(a, b);
for (point p : ps) {
bool ignored = false;
if (abs(p - b.s) < eps or abs(p - b.t) < eps) {
ignored = true;
}
if (not ignored) {
for (point q : a.ps) {
if (abs(p - q) < eps) {
ignored = true; // when the intersection point is one of the vertex of the polygon
break;
}
}
}
if (not ignored) return true;
}
return false;
}