Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const double eps = 1e-7;
- double pi = acos(-1);
- struct Point{
- double x = 0, y = 0;
- double angle;
- double len_2;
- double len;
- Point(double x, double y) : x(x), y(y) {
- angle = atan2(y, x);
- len_2 = x*x + y*y;
- len = sqrt(len_2);
- }
- Point() {}
- Point rationing() const {
- return *this / len;
- }
- Point operator / (double k) const {
- return Point(x / k, y / k);
- }
- Point rotate(double da){
- da += angle;
- return Point(len * cos(da), len * sin(da));
- }
- };
- bool operator < (const Point& p, const Point& q){
- return p.x < q.x - eps || p.x < q.x + eps && p.y < q.y;
- }
- Point operator * (double k, const Point& p){
- return Point(p.x * k, p.y * k);
- }
- Point operator - (const Point& p, const Point& q){
- return Point(p.x - q.x, p.y - q.y);
- }
- Point operator + (const Point& p, const Point& q){
- return Point(p.x + q.x, p.y + q.y);
- }
- istream& operator >> (istream& in, Point& p){
- double x, y;
- cin >> x >> y;
- p = Point(x, y);
- return in;
- }
- ostream& operator << (ostream& out, const Point& p){
- out << p.x << ' ' << p.y;
- return out;
- }
- double angle_between(const Point& p, const Point& q){
- double a = abs(p.angle - q.angle);
- return min(a, 2*pi - a);
- }
- double vect(const Point& p, const Point& q){
- return p.x*q.y - p.y*q.x;
- }
- double scal(const Point& p, const Point& q){
- return p.x*q.x + p.y*q.y;
- }
- double dst_2(const Point& p, const Point& q){
- double x = p.x - q.x;
- double y = p.y - q.y;
- return x*x + y*y;
- }
- double area2(vector<Point>& a){
- Point p;
- Point last = a.back();
- double s = 0;
- for (auto cur : a){
- s += vect(cur - p, last - p);
- last = cur;
- }
- return abs(s);
- }
- struct Line{
- double a, b, c;
- Point v;
- Line (double A, double B, double C) : a(A), b(B), c(C) {
- double len = Point(a, b).len;
- a /= len; b /= len; c /= len;
- if (a < 0 || a == 0 && b < 0){
- a *= -1; b *= -1; c *= -1;
- }
- v = Point(-b, a);
- }
- Line (const Point& p, const Point& q){
- a = p.y - q.y;
- b = q.x - p.x;
- c = -(p.x*a + p.y*b);
- *this = Line(a, b, c);
- }
- Line (){}
- double distance(const Point& p) const {
- return abs(a*p.x + b*p.y + c);
- }
- double vect(const Point& p) const {
- return a*p.x + b*p.y + c;
- }
- };
- istream& operator >> (istream& in, Line& l){
- double a, b, c;
- cin >> a >> b >> c;
- l = Line(a, b, c);
- return in;
- }
- ostream& operator << (ostream& out, const Line& l){
- out << l.a << ' ' << l.b << ' ' << l.c << endl;
- return out;
- }
- pair<int, Point> intersect(const Line& l, const Line& m){
- double z = l.a * m.b - l.b * m.a;
- if (z == 0){
- if (l.c == m.c){
- return {1, Point()};
- }
- return {-1, Point()};
- }
- double x = -(l.c * m.b - l.b * m.c) / z;
- double y = -(l.a * m.c - l.c * m.a) / z;
- return {0, Point(x, y)};
- }
- struct Beam {
- Line l;
- Point v;
- Point b;
- Beam (const Point& p, const Point& q) : b(p), v(q), l(p, q){}
- Beam (){}
- double distance(const Point& p) const {
- if (scal(v - b, p - b) < 0){
- return sqrt(dst_2(b, p));
- }
- return l.distance(p);
- }
- bool in_sector(const Point& p) const {
- return scal(v - b, p - b) > -eps;
- }
- };
- double distance(const Beam& a, const Beam& b){
- const auto& res = intersect(a.l, b.l);
- if (res.first == 0){
- const Point& p = res.second;
- // cout << p << endl;
- if (a.in_sector(p) && b.in_sector(p)){
- return 0;
- }
- }
- return min(a.distance(b.b), b.distance(a.b));
- }
- struct Segment {
- Point p, q;
- Beam b1, b2;
- Line l;
- Segment (Point p, Point q) : p(min(p, q)), q(max(p, q)), b1(p, q), b2(q, p), l(p, q) {}
- Segment () {}
- double distance(const Point& p) const {
- return max(b1.distance(p), b2.distance(p));
- }
- bool in_sector(const Point& p) const {
- return b1.in_sector(p) && b2.in_sector(p);
- }
- };
- istream& operator >> (istream& in, Segment& s){
- Point p, q;
- cin >> p >> q;
- s = Segment(p, q);
- return in;
- }
- double distance(const Segment& s, const Segment& t){
- const auto& res = intersect(s.l, t.l);
- if (res.first == 0){
- const Point& p = res.second;
- if (s.in_sector(p) && t.in_sector(p)){
- return 0;
- }
- }
- return min(
- min(s.distance(t.p), s.distance(t.q)),
- min(t.distance(s.p), t.distance(s.q))
- );
- }
- void solve(){
- }
- main(){
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- cout << fixed << setprecision(10);
- freopen("raydist.in", "r", stdin);
- freopen("raydist.out", "w", stdout);
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement