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>
- #ifdef AC
- #define __GLIBCXX_DEBUG
- #define __GLIBCXX_ASSERT
- #endif
- 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;
- const ld PI = 3.14159265358979L;
- ld toGradus (ld rad) { return (180 * rad) / PI; }
- ld toRad (ld gradus) { return (PI * gradus) / 180; }
- // 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}; }
- ld ang (Vector a, Vector b) {
- return atan2(a * b, a % b);
- }
- // 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;
- }
- }
- namespace circleGeometry {
- using namespace floatGeometry;
- typedef pair<Point, Point> twoPoints;
- struct Circle { Point O; ld r; };
- istream &operator>> (istream &s, Circle &c)
- { return s >> c.O >> c.r; }
- ostream &operator<< (ostream &s, Circle c)
- { return s << c.O << " " << c.r; }
- twoPoints intersect (Circle c, Line l) {
- ld d = dist(l, c.O); //addlog("dist =", d);
- if (c.r < d - eps) return {NO_POINT, NO_POINT};
- ld L = sqrt( c.r * c.r - d * d );
- Vector perL{ l.a, l.b };
- Vector OH = perL * (d / abs(perL));
- Point H = c.O + OH; if (!has(l, H)) H = c.O - OH; assert(has(l, H)); // ????
- Vector parL = turn90(perL);
- Vector dH = parL * (L / abs(parL));
- twoPoints res = {H + dH, H - dH};
- if (eq(c.r, d)) {
- assert(res.first == res.second);
- res.first = NO_POINT;
- } return res;
- }
- Point _check (Point p, Segment s) {
- if (p == NO_POINT || p == POINTS || has(s, p)) return p;
- return NO_POINT;
- }
- twoPoints intersect (Circle c, Segment s) {
- Line l(s);
- twoPoints tp = intersect(c, l);
- twoPoints res{ _check(tp.first, s), _check(tp.second, s) };
- if (res.second == NO_POINT) swap(res.first, res.second);
- return res;
- }
- }
- using namespace circleGeometry;
- int main () {
- for (Vector a, b; cin >> a >> b; )
- pcout << ang(a, b) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement