Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <cassert>
- #include <cstdio>
- #include <iostream>
- #include <iomanip>
- #include <vector>
- using namespace std;
- #define all(x) begin(x), end(x)
- template<class A> void addlog(A a) { cerr << a << endl; }
- template<class A, class... B> void addlog(A a, B... b)
- { cerr << a << ' '; addlog(b...); }
- namespace floatGeometry {
- // Types
- #define pcout cout << fixed << setprecision(7)
- typedef long long ll;
- typedef long double ld;
- const ld eps = 1e-12;
- const ld inf = 1e+12;
- bool eq (ld a, ld b) { return abs(a - b) < eps; }
- ld abs (ld x) { return (x > 0? x : -x); }
- struct Point { ld x, y; };
- typedef Point Vector;
- // Constants
- const Point NO_POINT {19, -inf},
- POINTS {19, +inf};
- // Point
- ld abs (Point p) { return hypot(p.x, p.y); }
- ld ang (Point p) { return atan2(p.y, p.x); }
- bool operator== (Point a, Point b)
- { return eq(a.x, b.x) && eq(a.y, b.y); }
- bool operator!= (Point a, Point b)
- { return !(a == b); }
- // Vector
- Vector operator- (Vector v)
- { return Vector{ -v.x, -v.y }; }
- Vector operator+ (Vector a, Vector b)
- { return Vector{ a.x+b.x, a.y+b.y }; }
- Vector operator- (Vector a, Vector b)
- { return Vector{ a.x-b.x, a.y-b.y }; }
- Vector operator* (Vector v, ld alpha)
- { return Vector{ alpha * v.x, alpha * v.y }; }
- ld operator* (Vector a, Vector b)
- { return a.x*b.y - b.x*a.y; }
- ld operator% (Vector a, Vector b)
- { return a.x*b.x + a.y*b.y; }
- Vector turn90 (Vector v)
- { return Vector{v.y, -v.x}; }
- // I/O.
- istream& operator>> (istream& s, Point &p)
- { return s >> p.x >> p.y; }
- ostream& operator<< (ostream &s, Point p)
- { return s << p.x << ' ' << p.y; }
- struct Segment { Point p, q; };
- ld abs (Segment s) { return abs(s.p - s.q); }
- istream& operator>> (istream &s, Segment &x)
- { return s >> x.p >> x.q; }
- ostream& operator<< (ostream &s, Segment x)
- { return s << x.p << " " << x.q; }
- struct Line { ld a, b, c; Line () {}
- void normalize () {
- ld z = hypot(a, b);
- if (eq(a, 0)) { if (b < 0) z = -z; }
- else if (a < 0) z = -z;
- a /= z; b /= z; c /= z;
- assert(eq(hypot(a, b), 1));
- } Line (Point p, Point q) {
- a = p.y - q.y; b = q.x - p.x;
- c = - (a * p.x + b * p.y );
- normalize();
- } Line (Segment s) : Line(s.p, s.q) {}
- };
- // Line
- ld vMul (ld ax, ld ay, ld bx, ld by) { return ax*by - bx*ay; }
- Point intersect (Line I, Line II) {
- ld D0 = vMul(I.a, I.b, II.a, II.b);
- ld Dx = vMul(I.b, I.c, II.b, II.c);
- ld Dy = vMul(I.c, I.a, II.c, II.a);
- if (eq(D0, 0)) {
- assert(eq(Dx, Dy));
- if (eq(Dx, 0)) return POINTS;
- else return NO_POINT;
- } return Point{Dx / D0, Dy / D0};
- }
- // I/O
- istream& operator>> (istream& s, Line &l)
- { return s >> l.a >> l.b >> l.c; }
- ostream& operator<< (ostream& s, Line l)
- { return s << l.a << ' ' << l.b << ' ' << l.c; }
- struct Ray {
- Point p; Vector v; Line l;
- Ray (Point P, Vector V) : p(P), v(V), l(p, p + v) {}
- };
- ld signDist (Line l, Point p) {
- l.normalize();
- return l.a * p.x + l.b * p.y + l.c;
- } ld dist (Line l, Point p) { return abs(signDist(l, p)); }
- ld dist (Ray r, Point p) {
- if ( (p - r.p) % r.v > -eps )
- return dist(r.l, p);
- else return abs(p - r.p);
- }
- ld dist (Segment s, Point p) {
- Ray r1 (s.p, s.q - s.p),
- r2 (s.q, s.p - s.q);
- return max(dist(r1, p), dist(r2, p));
- }
- template <class G> bool
- has (G g, Point p)
- { return eq(dist(g, p), 0); }
- Point intersect (Segment a, Segment b) {
- Line la(a), lb(b);
- Point p = intersect(la, lb);
- if (p == POINTS) {
- // Return one of that points.
- if (has(a, b.p)) return b.p;
- if (has(a, b.q)) return b.q;
- if (has(b, a.p)) return a.p;
- if (has(b, a.q)) return a.q;
- assert(false);
- } else if (p != NO_POINT && has(a, p) && has(b, p)) {
- return p;
- } else
- return NO_POINT;
- }
- }
- using namespace floatGeometry;
- int main () {
- for (Segment a, b; cin >> a >> b; )
- pcout << intersect(a, b) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement