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