template <class T> struct RVector2 {
public:
typedef T TElement;
template <int x> struct ExpandingSwizzler2 {
struct {
T v[2];
};
ExpandingSwizzler2<x>& operator=(const T& right) {
v[0] = right;
v[1] = right;
return *this;
}
operator RVector2<T> () const {
RVector2<T> r = { v[x], v[x] };
return r;
}
};
template <int x, int y> struct Swizzler2 {
struct {
T v[2];
};
Swizzler2<x, y>& operator= (const RVector2<T>& right) {
T ex = right.x;
T ey = right.y;
v[x] = ex;
v[y] = ey;
return *this;
}
operator RVector2<T> () const {
RVector2<T> r = { v[x], v[y] };
return r;
}
};
union {
struct {
T x, y;
};
struct {
T u, v;
};
T cell[2];
ExpandingSwizzler2<0> xx;
ExpandingSwizzler2<1> yy;
Swizzler2<0, 1> xy;
Swizzler2<1, 0> yx;
ExpandingSwizzler2<0> uu;
ExpandingSwizzler2<1> vv;
Swizzler2<0, 1> uv;
Swizzler2<1, 0> vu;
};
T DistanceToSquared (const RVector2<T>& to) const {
T tx = to.x - x;
T ty = to.y - y;
return tx * tx + ty * ty;
}
RVector2<T> Direction (const RVector2<T>& to) const {
RVector2<T> direction = to - *this;
direction.Normalize();
return direction;
}
T Dot (const RVector2<T>& right) const {
return x * right.x + y * right.y;
}
T Cross (const RVector2<T>& right) const {
return x * right.y - right.x * y;
}
int Quadrant () const {
int quad = 0;
quad |= ((x >= 0));
quad |= ((y >= 0) << 1);
return quad;
}
int Quadrant (const RVector2<T>& origin) const {
int quad = 0;
quad |= ((x >= origin.x));
quad |= ((y >= origin.y) << 1);
return quad;
}
bool QuadrantChange ( const RVector2<T>& after, const RVector2<T>& origin ) const {
RVector2<T> bOrigin = *this - origin;
RVector2<T> aOrigin = after - origin;
return ( !( (aOrigin.x > 0) == (bOrigin.x > 0) ) ||
!( (aOrigin.y > 0) == (bOrigin.y > 0) ) )
// Quadrant has changed
;
}
bool QuadrantChange ( const RVector2<T>& after ) const {
return ( !( (after.x > 0) == (x > 0) ) ||
!( (after.y > 0) == (y > 0) ) )
// Quadrant has changed
;
}
bool IsUnit () const {
return ( x * x + y * y ) == 1;
}
RVector2<T>& operator= (const RVector2<T>& right) {
x = right.x;
y = right.y;
return *this;
}
RVector2<T>& operator-= (const RVector2<T>& right) {
x -= right.x;
y -= right.y;
return *this;
}
RVector2<T>& operator+= (const RVector2<T>& right) {
x += right.x;
y += right.y;
return *this;
}
RVector2<T>& operator*= (const RVector2<T>& right) {
x *= right.x;
y *= right.y;
return *this;
}
RVector2<T>& operator/= (const RVector2<T>& right) {
x /= right.x;
y /= right.y;
return *this;
}
RVector2<T>& operator*= (const T& right) {
x *= right;
y *= right;
return *this;
}
RVector2<T>& operator/= (const T& right) {
T invright = 1 / right;
x *= invright;
y *= invright;
return *this;
}
RVector2<T>& operator++ () {
++x;
++y;
return *this;
}
RVector2<T>& operator-- () {
--x;
--y;
return *this;
}
RVector2<T> operator++ (int) {
RVector2<T> r = {x++, y++};
return r;
}
RVector2<T> operator-- (int) {
RVector2<T> r = {x--, y--};
return r;
}
RVector2<T> operator- (const RVector2<T>& right) const {
RVector2<T> r = {x - right.x, y - right.y};
return r;
}
RVector2<T> operator+ (const RVector2<T>& right) const {
RVector2<T> r = {x + right.x, y + right.y};
return r;
}
RVector2<T> operator* (const RVector2<T>& right) const {
RVector2<T> r = {x * right.x, y * right.y};
return r;
}
RVector2<T> operator/ (const RVector2<T>& right) const {
RVector2<T> r = {x / right.x, y / right.y};
return r;
}
RVector2<T> operator* (const T& right) const {
RVector2<T> r = {x * right, y * right};
return r;
}
RVector2<T> operator/ (const T& right) const {
T invright = 1 / right;
RVector2<T> r = {x * invright, y * invright};
return r;
}
RVector2<T> operator+ () const {
RVector2<T> r = {+x, +y};
return r;
}
RVector2<T> operator- () const {
RVector2<T> r = {-x, -y};
return r;
}
bool operator== (const RVector2<T>& right) const {
return right.x == x && right.y == y;
}
bool operator!= (const RVector2<T>& right) const {
return right.x != x || right.y != y;
}
operator T* () {
return (T*)cell;
}
operator T* () const {
return (T*)cell;
}
T& operator[] (int index) {
return cell[index];
}
T& operator[] (int index) const {
return *(T*)( cell + index );
}
};
int main (int argc, int argv) {
RVector2<float> arf = { 1.0f, 5.0f };
arf *= 2;
/// Muahahaha, aaahahahahaaaaaaaaaaa!
return 0;
}