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