Skip to the content.

:warning: library/geometry/Judge.hpp

Depends on

Code

#pragma once
#include "library/geometry/Base.hpp"
#include "library/geometry/UtilFunction.hpp"
namespace geometry {
bool is_orthogonal(Vector a, Vector b) { return is_equal(dot(a, b), 0.0); }
bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) {
    return is_orthogonal(a1 - a2, b1 - b2);
}
bool is_orthogonal(Segment s1, Segment s2) {
    return is_equal(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

bool is_parallel(Vector a, Vector b) { return is_equal(cross(a, b), 0.0); }
bool is_parallel(Point a1, Point a2, Point b1, Point b2) {
    return is_parallel(a1 - a2, b1 - b2);
}
bool is_parallel(Segment s1, Segment s2) {
    return is_equal(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

// bool is_intersect(Point p1,Point p2,Point p3,Point p4){
//   return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 and
//           ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
// }
// bool is_intersect(Segment s1,Segment s2){
//   return is_intersect(s1.p1,s1.p2,s2.p1,s2.p2);
// }
// bool is_intersect(Polygon p,Segment l){
//   int n=p.size();
//   for(int i=0;i<n;i++)
//     if(is_intersect(Segment(p[i],p[(i+1)%n]),l)) return 1;
//   return 0;
// }
//
// bool is_convex(Polygon p){
//  bool f=1;
//  int n=p.size();
//  for(int i=0;i<n;i++){
//    int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
//    f&=t!=CCW_CLOCKWISE;
//  }
//  return f;
//}
} // namespace geometry
#line 2 "library/r2/XY.hpp"
template <typename T> struct XY {
    T x, y;
    XY() = default;
    XY(T x, T y) : x(x), y(y) {}
    XY(const std::pair<T, T> &xy) : x(xy.first), y(xy.second) {}

    XY operator+() const { return *this; }
    XY operator-() const { return XY(-x, -y); }

    XY &operator++() {
        x++;
        y++;
        return *this;
    }
    XY &operator--() {
        x--;
        y--;
        return *this;
    }
    XY &operator++(int) {
        XY a = *this;
        ++*this;
        return a;
    }
    XY &operator--(int) {
        XY a = *this;
        --*this;
        return a;
    }

    XY &operator+=(const XY &v) {
        x += v.x;
        y += v.y;
        return *this;
    }
    XY &operator-=(const XY &v) {
        x -= v.x;
        y -= v.y;
        return *this;
    }
    XY &operator*=(const T &a) {
        x *= a;
        y *= a;
        return *this;
    }
    XY &operator/=(const T &a) {
        x /= a;
        y /= a;
        return *this;
    }

    friend XY operator+(const XY &u, const XY &v) { return XY(u) += v; }
    friend XY operator-(const XY &u, const XY &v) { return XY(u) -= v; }
    friend XY operator*(const XY &u, const T &a) { return XY(u) *= a; }
    friend XY operator*(const T &a, const XY &u) { return XY(u) *= a; }
    friend XY operator/(const XY &u, const T &a) { return XY(u) /= a; }

    bool operator<(const XY &v) const { return x != v.x ? x < v.x : y < v.y; }
    bool operator>(const XY &v) const { return x != v.x ? x > v.x : y > v.y; }
    bool operator==(const XY &v) const { return x == v.x and y == v.y; }
    bool operator<=(const XY &v) const { return !(*this > v); }
    bool operator>=(const XY &v) const { return !(*this < v); }
    bool operator!=(const XY &v) const { return !(*this == v); }

    double arg() const { return atan2(y, x); }

    // [0,2pi) で θ(u)<θ(v) の時 true
    // (0,0) は 2pi に相当
    // static bool angle_cmp(const XY&u,const XY&v){
    //  using U=conditional_t< is_same_v<T,int>,long long,T>;
    //  if(u==XY(0,0))return false;
    //  if(v==XY(0,0))return true;
    //  if(u.y==0){
    //    if(u.x>0)return true;
    //    if(v.y==0)return v.x<0;
    //    return v.y<0;
    //  }
    //  if(u.y>0){
    //    if(v.y==0)return v.x<0;
    //    if(v.y<0)return true;
    //    return U(v.x)*u.y <= U(u.x)*v.y;
    //  }
    //  if(v.y>=0)return false;
    //  return U(v.x)*u.y <= U(u.x)*v.y;
    //}

    friend T dot(const XY &u, const XY &v) { return u.x * v.x + u.y * v.y; }
    T norm() { return dot(*this, *this); }
    T abs() { return sqrt(norm()); }

    friend std::istream &operator>>(std::istream &is, XY &v) {
        is >> v.x >> v.y;
        return is;
    }
    friend std::ostream &operator<<(std::ostream &os, const XY &v) {
        os << v.x << " " << v.y;
        return os;
    }

    static XY direction(const char &c) {
        if (c == 'R')
            return {1, 0};
        if (c == 'L')
            return {-1, 0};
        if (c == 'U')
            return {0, -1};
        if (c == 'D')
            return {0, 1};
        return {0, 0};
    }
};
#line 3 "library/geometry/Base.hpp"
namespace geometry {
constexpr double EPS = 1e-10, PI = acos(-1);

bool is_equal(double a, double b) { return abs(a - b) < EPS; }

using Point = XY<double>;
bool cmp_y(const Point &p1, const Point &p2) {
    return p1.y != p2.y ? p1.y < p2.y : p1.x < p2.x;
}

using Vector = Point;
using Polygon = std::vector<Point>;

std::istream &operator>>(std::istream &is, Polygon &p) {
    for (Point &c : p)
        is >> c;
    return is;
}

struct Segment {
    Point p1, p2;
    Segment() {}
    Segment(Point p1, Point p2) : p1(p1), p2(p2) {}
    friend std::istream &operator>>(std::istream &is, Segment &s) {
        is >> s.p1 >> s.p2;
        return is;
    }
    double arg() const { return (p2 - p1).arg(); }
};
using Line = Segment;

struct Circle {
    Point c;
    double r;
    Circle() {}
    Circle(Point c, double r) : c(c), r(r) {}
    friend std::istream &operator>>(std::istream &is, Circle &c) {
        is >> c.c >> c.r;
        return is;
    }
};
} // namespace geometry
#line 3 "library/geometry/UtilFunction.hpp"
namespace geometry {
double cross(Vector a, Vector b) {
    // std::cerr << a <<" "<<b<<":"<<a.x*b.y-a.y*b.x<<endl;
    return a.x * b.y - a.y * b.x;
}

Point orth(Point p) { return Point(-p.y, p.x); }

Point project(Segment s, Point p) {
    Vector base = s.p2 - s.p1;
    double r = dot(p - s.p1, base) / base.norm();
    return s.p1 + base * r;
}

Point reflect(Segment s, Point p) { return p + (project(s, p) - p) * 2.0; }

Polygon convex_hull(Polygon ps) {
    int n = ps.size();
    std::ranges::sort(ps, cmp_y);
    int k = 0;
    Polygon qs(n * 2);
    for (int i = 0; i < n; i++) {
        while (k > 1 and cross(qs[k - 1] - qs[k - 2], ps[i] - qs[k - 1]) < 0)
            k--;
        qs[k++] = ps[i];
    }
    for (int i = n - 2, t = k; i >= 0; i--) {
        while (k > t and cross(qs[k - 1] - qs[k - 2], ps[i] - qs[k - 1]) < 0)
            k--;
        qs[k++] = ps[i];
    }
    qs.resize(k - 1);
    return qs;
}
} // namespace geometry
#line 4 "library/geometry/Judge.hpp"
namespace geometry {
bool is_orthogonal(Vector a, Vector b) { return is_equal(dot(a, b), 0.0); }
bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) {
    return is_orthogonal(a1 - a2, b1 - b2);
}
bool is_orthogonal(Segment s1, Segment s2) {
    return is_equal(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

bool is_parallel(Vector a, Vector b) { return is_equal(cross(a, b), 0.0); }
bool is_parallel(Point a1, Point a2, Point b1, Point b2) {
    return is_parallel(a1 - a2, b1 - b2);
}
bool is_parallel(Segment s1, Segment s2) {
    return is_equal(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

// bool is_intersect(Point p1,Point p2,Point p3,Point p4){
//   return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 and
//           ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
// }
// bool is_intersect(Segment s1,Segment s2){
//   return is_intersect(s1.p1,s1.p2,s2.p1,s2.p2);
// }
// bool is_intersect(Polygon p,Segment l){
//   int n=p.size();
//   for(int i=0;i<n;i++)
//     if(is_intersect(Segment(p[i],p[(i+1)%n]),l)) return 1;
//   return 0;
// }
//
// bool is_convex(Polygon p){
//  bool f=1;
//  int n=p.size();
//  for(int i=0;i<n;i++){
//    int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
//    f&=t!=CCW_CLOCKWISE;
//  }
//  return f;
//}
} // namespace geometry
Back to top page