#ifndef VECTOR_H
#define VECTOR_H
#include <cmath>
#include "real.h"
class Vector {
public:
union {
struct { Real x, y; };
struct { Real coords[2]; };
};
explicit Vector(const Real &x = Real(), const Real &y = Real()): x(x), y(y) { }
const Real& operator[] (int i) const { return coords[i]; }
Real& operator[] (int i) { return coords[i]; }
bool operator< (const Vector &a) const { return less(x, a.x) || (!less(a.x, x) && less(y, a.y)); }
bool operator== (const Vector &a) const { return equal(x, a.x) && equal(y, a.y); }
bool operator!= (const Vector &a) const { return !(*this == a); }
Vector operator+ (const Vector &a) const { return Vector(x + a.x, y + a.y); }
Vector operator- (const Vector &a) const { return Vector(x - a.x, y - a.y); }
Vector operator* (const Real &a) const { return Vector(x*a, y*a); }
Vector operator/ (const Real &a) const { return *this * (Real(1)/a); }
Vector& operator+= (const Vector &a) { x += a.x; y += a.y; return *this; }
Vector& operator-= (const Vector &a) { x -= a.x; y -= a.y; return *this; }
Vector& operator*= (const Real &a) { x *= a; y *= a; return *this; }
Vector& operator/= (const Real &a) { return *this *= (Real(1)/a); }
friend inline Vector operator*(const Real &a, const Vector &b) { return b*a; }
friend inline Real dot(const Vector &a, const Vector &b) { return a.x*b.x + a.y*b.y; }
bool iszero() const { return *this == Vector(); }
void reset() { *this = Vector(); }
Real lensqr() const { return dot(*this, *this); }
Real len() const { return sqrt(lensqr()); }
Vector norm() const { return iszero() ? Vector() : *this/len(); }
Vector perp() const { return Vector(-y, x); }
Vector scale(const Vector &a) const { return Vector(x*a.x, y*a.y); }
Vector rotate(const Real &angle) const {
Vector a = from_angle(angle);
return Vector(x*a.x - y*a.y, x*a.y + y*a.x);
}
static Vector from_angle(Real angle)
{ return Vector(cos(angle), sin(angle)); }
};
class Segment {
public:
Vector p0, p1, t0, t1;
explicit Segment(
const Vector &p0 = Vector(),
const Vector &p1 = Vector(),
const Vector &t0 = Vector(),
const Vector &t1 = Vector()
):
p0(p0), p1(p1), t0(t0), t1(t1) { }
bool operator< (const Segment &a) const {
return p0 < a.p0 ? true : a.p0 < p0 ? false
: p1 < a.p1 ? true : a.p1 < p1 ? false
: t0 < a.t0 ? true : a.t0 < t0 ? false
: t1 < a.t1;
}
bool operator> (const Segment &a) const { return a < *this; }
bool operator== (const Segment &a) const { return p0 == a.p0 && p1 == a.p1 && t0 == a.t0 && t1 == a.t1; }
bool operator!= (const Segment &a) const { return !(*this == a); }
Vector p(const Real &l) const {
return p0*((( 2.0*l - 3.0)*l )*l + 1.0)
+ p1*(((-2.0*l + 3.0)*l )*l )
+ t0*((( l - 2.0)*l + 1.0)*l )
+ t1*((( l - 1.0)*l )*l );
}
Vector t(const Real &l) const {
return p0*(( 6.0*l - 6.0)*l )
+ p1*((-6.0*l + 6.0)*l )
+ t0*(( 3.0*l - 4.0)*l + 1.0)
+ t1*(( 3.0*l - 2.0)*l );
}
Vector operator() (const Real &l) const { return p(l); }
Segment sub(const Real &a, const Real &b) const { return Segment(p(a), p(b), t(a), t(b)); }
};
#endif