55502f40dc8b7c769880b10874abc9d0

for my 3d game :) still working on Matrix4<T>...

#pragma once

#include <iostream>

namespace Rage {
    template <typename T>
    class Vector2 {
    private:
        T _a[2];

    public:
        static const Vector2<T> Zero;
        static const Vector2<T> One;
        static const Vector2<T> UnitX;
        static const Vector2<T> UnitY;

        Vector2(const Vector2<T> & v = Zero) {
            _a[0] = v[0];
            _a[1] = v[1];
        }

        Vector2(T x, T y) {
            _a[0] = x;
            _a[1] = y;
        }

        T X() const { return _a[0]; }
        T Y() const { return _a[1]; }

        T & operator [] (int i) { return _v[i]; }
        const T & operator [] (int i) const { return _a[i]; }

        void Normalize() {
            T scale = 1 / GetLength();
            _a[0] *= scale;
            _a[1] *= scale;
        }

        T GetLength() const {
            return sqrt(GetLengthSquared());
        }

        T GetLengthSquared() const {
            return _a[0] * _a[0] + _a[1] * _a[1];
        }

        static Vector2<T> Lerp(const Vector2<T> & a, const Vector2<T> & b, T blend) {
            Vector2<T> r(a);
            r[0] = blend * (b[0] - a[0]) + a[0];
            r[1] = blend * (b[1] - a[1]) + a[1];
            return r;
        }

        Vector2<T> operator - () const {
            Vector2<T> r;
            r[0] = -_a[0];
            r[1] = -_a[1];
            return r;
        }

        bool operator == (const Vector2<T> & rhs) const {
            bool r = true;
            r &= _a[0] == rhs[0];
            r &= _a[1] == rhs[1];
            return r;
        }

        bool operator != (const Vector2<T> & rhs) const {
            bool r = true;
            r &= _a[0] != rhs[0];
            r &= _a[1] != rhs[1];
            return r;
        }

        Vector2<T> & operator /= (T rhs) {
            if (rhs != 0) {
                _a[0] /= rhs;
                _a[1] /= rhs;
            }
            return *this;
        }

        Vector2<T> & operator /= (const Vector2<T> & rhs) {
            if (rhs[0] != 0)
                _a[0] /= rhs[0];
            if (rhs[1] != 0)
                _a[1] /= rhs[1];
            return *this;
        }

        Vector2<T> & operator *= (const T rhs) {
            _a[0] *= rhs;
            _a[1] *= rhs;
            return *this;
        }

        Vector2<T> & operator *= (const Vector2<T> & rhs) {
            _a[0] *= rhs[0];
            _a[1] *= rhs[1];
            return *this;
        }

        Vector2<T> & operator += (const T rhs) {
            _a[0] += rhs;
            _a[1] += rhs;
            return *this;
        }

        Vector2<T> & operator += (const Vector2<T> & rhs) {
            _a[0] += rhs[0];
            _a[1] += rhs[1];
            return *this;
        }

        Vector2<T> & operator -= (const T rhs) {
            _a[0] -= rhs;
            _a[1] -= rhs;
            return *this;
        }

        Vector2<T> & operator -= (const Vector2<T> & rhs) {
            _a[0] -= rhs[0];
            _a[1] -= rhs[1];
            return *this;
        }

        Vector2<T> & operator / (const T rhs) const {
            Vector2<T> r(*this);
            return r /= rhs;
        }

        Vector2<T> & operator / (const Vector2<T> & rhs)  const {
            Vector2<T> r(*this);
            return r /= rhs;
        }

        Vector2<T> & operator * (const T rhs) const {
            Vector2<T> r(*this);
            return r *= rhs;
        }

        Vector2<T> & operator * (const Vector2<T> & rhs) const {
            Vector2<T> r(*this);
            return r *= rhs;
        }

        Vector2<T> & operator + (const T rhs) const {
            Vector2<T> r(*this);
            return r *= rhs;
        }

        Vector2<T> & operator + (const Vector2<T> & rhs) const {
            Vector2<T> r(*this);
            return r += rhs;
        }

        Vector2<T> & operator - (const T rhs) const {
            Vector2<T> r(*this);
            return r -= rhs;
        }

        Vector2<T> & operator - (const Vector2<T> & rhs) const {
            Vector2<T> r(*this);
            return r -= rhs;
        }
    };

    template <typename T>
    std::ostream & operator << (std::ostream & s, const Vector2<T> & rhs) {
        s << '(' << rhs[0] << ", ";
        s << rhs[1] << ')';
        return s;
    }

    template <typename T>
    std::istream & operator >> (std::istream & s, Vector2<T> & rhs)	{
        s >> rhs[0];
        s >> rhs[1];
        return s;
    }

    template <typename T>
    const Vector2<T> Vector2<T>::Zero(T(0), T(0));

    template <typename T>
    const Vector2<T> Vector2<T>::One(T(1), T(1));

    template <typename T>
    const Vector2<T> Vector2<T>::UnitX(T(1), T(0));

    template <typename T>
    const Vector2<T> Vector2<T>::UnitY(T(0), T(1));

    typedef Vector2<float> Vector2f;
    typedef Vector2<double> Vector2d;

    template <typename T>
    class Vector3 {
    private:
        T _a[3];

    public:
        static const Vector3<T> Zero;
        static const Vector3<T> One;
        static const Vector3<T> UnitX;
        static const Vector3<T> UnitY;
        static const Vector3<T> UnitZ;

        Vector3(const Vector3<T> & v = Zero) {
            _a[0] = v[0];
            _a[1] = v[1];
            _a[2] = v[2];
        }

        Vector3(T x, T y, T z) {
            _a[0] = x;
            _a[1] = y;
            _a[2] = z;
        }

        T X() const { return _a[0]; }
        T Y() const { return _a[1]; }
        T Z() const { return _a[2]; }

        T & operator [] (int i) { return _a[i]; }
        const T & operator [] (int i) const { return _a[i]; }

        void Normalize() {
            T scale = 1 / GetLength();
            _a[0] *= scale;
            _a[1] *= scale;
            _a[2] *= scale;
        }

        T GetLength() const {
            return sqrt(GetLengthSquared());
        }

        T GetLengthSquared() const {
            return _a[0] * _a[0] + _a[1] * _a[1] + _a[2] * _a[2];
        }

        friend Vector3<T> Cross(const Vector3<T> & lhs, const Vector3<T> & rhs) {
            Vector3<T> r(lhs);
            r[0] = r[1] * rhs[2] - r[2] * rhs[1];
            r[1] = r[2] * rhs[0] - r[0] * rhs[2];
            r[2] = r[0] * rhs[1] - r[1] * rhs[0];
            return r;
        }

        static Vector3<T> Lerp(const Vector3<T> & a, const Vector3<T> & b, T blend) {
            Vector3<T> r(a);
            r[0] = blend * (b[0] - a[0]) + a[0];
            r[1] = blend * (b[1] - a[1]) + a[1];
            r[2] = blend * (b[2] - a[2]) + a[2];
            return r;
        }

        Vector3<T> operator - () const {
            Vector3<T> r;
            r[0] = -_a[0];
            r[1] = -_a[1];
            r[2] = -_a[2];
            return r;
        }

        bool operator == (const Vector3<T> & rhs) const {
            bool r = true;
            r &= _a[0] == rhs[0];
            r &= _a[1] == rhs[1];
            r &= _a[2] == rhs[2];
            return r;
        }

        bool operator != (const Vector3<T> & rhs) const {
            bool r = true;
            r &= _a[0] != rhs[0];
            r &= _a[1] != rhs[1];
            r &= _a[2] != rhs[2];
            return r;
        }

        Vector3<T> & operator /= (T rhs) {
            if (rhs != 0) {
                _a[0] /= rhs;
                _a[1] /= rhs;
                _a[2] /= rhs;
            }
            return *this;
        }

        Vector3<T> & operator /= (const Vector3<T> & rhs) {
            if (rhs[0] != 0)
                _a[0] /= rhs[0];
            if (rhs[1] != 0)
                _a[1] /= rhs[1];
            if (rhs[2] != 0)
                _a[2] /= rhs[2];
            return *this;
        }

        Vector3<T> & operator *= (const T rhs) {
            _a[0] *= rhs;
            _a[1] *= rhs;
            _a[2] *= rhs;
            return *this;
        }

        Vector3<T> & operator *= (const Vector3<T> & rhs) {
            _a[0] *= rhs[0];
            _a[1] *= rhs[1];
            _a[2] *= rhs[2];
            return *this;
        }

        Vector3<T> & operator += (const T rhs) {
            _a[0] += rhs;
            _a[1] += rhs;
            _a[2] += rhs;
            return *this;
        }

        Vector3<T> & operator += (const Vector3<T> & rhs) {
            _a[0] += rhs[0];
            _a[1] += rhs[1];
            _a[2] += rhs[2];
            return *this;
        }

        Vector3<T> & operator -= (const T rhs) {
            _a[0] -= rhs;
            _a[1] -= rhs;
            _a[2] -= rhs;
            return *this;
        }

        Vector3<T> & operator -= (const Vector3<T> & rhs) {
            _a[0] -= rhs[0];
            _a[1] -= rhs[1];
            _a[2] -= rhs[2];
            return *this;
        }

        Vector3<T> & operator / (const T rhs) const {
            Vector3<T> r(*this);
            return r /= rhs;
        }

        Vector3<T> & operator / (const Vector3<T> & rhs)  const {
            Vector3<T> r(*this);
            return r /= rhs;
        }

        Vector3<T> & operator * (const T rhs) const {
            Vector3<T> r(*this);
            return r *= rhs;
        }

        Vector3<T> & operator * (const Vector3<T> & rhs) const {
            Vector3<T> r(*this);
            return r *= rhs;
        }

        Vector3<T> & operator + (const T rhs) const {
            Vector3<T> r(*this);
            return r *= rhs;
        }

        Vector3<T> & operator + (const Vector3<T> & rhs) const {
            Vector3<T> r(*this);
            return r += rhs;
        }

        Vector3<T> & operator - (const T rhs) const {
            Vector3<T> r(*this);
            return r -= rhs;
        }

        Vector3<T> & operator - (const Vector3<T> & rhs) const {
            Vector3<T> r(*this);
            return r -= rhs;
        }
    };

    template <typename T>
    std::ostream & operator << (std::ostream & s, const Vector3<T> & rhs) {
        s << '(' << rhs[0] << ", ";
        s << rhs[1] << ", ";
        s << rhs[2] << ')';
        return s;
    }

    template <typename T>
    std::istream & operator >> (std::istream & s, Vector3<T> & rhs)	{
        s >> rhs[0];
        s >> rhs[1];
        s >> rhs[2];
        return s;
    }

    template <typename T>
    const Vector3<T> Vector3<T>::Zero(T(0), T(0), T(0));

    template <typename T>
    const Vector3<T> Vector3<T>::One(T(1), T(1), T(1));

    template <typename T>
    const Vector3<T> Vector3<T>::UnitX(T(1), T(0), T(0));

    template <typename T>
    const Vector3<T> Vector3<T>::UnitY(T(0), T(1), T(0));

    template <typename T>
    const Vector3<T> Vector3<T>::UnitZ(T(0), T(0), T(1));

    typedef Vector3<float> Vector3f;
    typedef Vector3<double> Vector3d;

    template <typename T>
    class Vector4 {
    private:
        T _a[4];

    public:
        static const Vector4<T> Zero;
        static const Vector4<T> One;
        static const Vector4<T> UnitX;
        static const Vector4<T> UnitY;
        static const Vector4<T> UnitZ;
        static const Vector4<T> UnitW;

        Vector4(const Vector4<T> & v = Zero) {
            _a[0] = v[0];
            _a[1] = v[1];
            _a[2] = v[2];
            _a[3] = v[3];
        }

        Vector4(T x, T y, T z, T w) {
            _a[0] = x;
            _a[1] = y;
            _a[2] = z;
            _a[3] = w;
        }

        T X() const { return _a[0]; }
        T Y() const { return _a[1]; }
        T Z() const { return _a[2]; }
        T W() const { return _a[3]; }

        T & operator [] (int i) { return _a[i]; }
        const T & operator [] (int i) const { return _a[i]; }

        void Normalize() {
            T scale = 1 / GetLength();
            _a[0] *= scale;
            _a[1] *= scale;
            _a[2] *= scale;
            _a[3] *= scale;
        }

        T GetLength() const {
            return sqrt(GetLengthSquared());
        }

        T GetLengthSquared() const {
            return _a[0] * _a[0] + _a[1] * _a[1] + _a[2] * _a[2] + _a[3] * _a[3];
        }

        static Vector4<T> Lerp(const Vector4<T> & a, const Vector4<T> & b, T blend) {
            Vector4<T> r(a);
            r[0] = blend * (b[0] - a[0]) + a[0];
            r[1] = blend * (b[1] - a[1]) + a[1];
            r[2] = blend * (b[2] - a[2]) + a[2];
            r[3] = blend * (b[3] - a[3]) + a[3];
            return r;
        }

        Vector4<T> operator - () const {
            Vector4<T> r;
            r[0] = -_a[0];
            r[1] = -_a[1];
            r[2] = -_a[2];
            r[3] = -_a[3];
            return r;
        }

        bool operator == (const Vector4<T> & rhs) const {
            bool r = true;
            r &= _a[0] == rhs[0];
            r &= _a[1] == rhs[1];
            r &= _a[2] == rhs[2];
            r &= _a[3] == rhs[3];
            return r;
        }

        bool operator != (const Vector4<T> & rhs) const {
            bool r = true;
            r &= _a[0] != rhs[0];
            r &= _a[1] != rhs[1];
            r &= _a[2] != rhs[2];
            r &= _a[3] != rhs[3];
            return r;
        }

        Vector4<T> & operator /= (T rhs) {
            if (rhs != 0) {
                _a[0] /= rhs;
                _a[1] /= rhs;
                _a[2] /= rhs;
                _a[3] /= rhs;
            }
            return *this;
        }

        Vector4<T> & operator /= (const Vector4<T> & rhs) {
            if (rhs[0] != 0)
                _a[0] /= rhs[0];
            if (rhs[1] != 0)
                _a[1] /= rhs[1];
            if (rhs[2] != 0)
                _a[2] /= rhs[2];
            if (rhs[3] != 0)
                _a[3] /= rhs[2];
            return *this;
        }

        Vector4<T> & operator *= (const T rhs) {
            _a[0] *= rhs;
            _a[1] *= rhs;
            _a[2] *= rhs;
            _a[3] *= rhs;
            return *this;
        }

        Vector4<T> & operator *= (const Vector4<T> & rhs) {
            _a[0] *= rhs[0];
            _a[1] *= rhs[1];
            _a[2] *= rhs[2];
            _a[3] *= rhs[3];
            return *this;
        }

        Vector4<T> & operator += (const T rhs) {
            _a[0] += rhs;
            _a[1] += rhs;
            _a[2] += rhs;
            _a[3] += rhs;
            return *this;
        }

        Vector4<T> & operator += (const Vector4<T> & rhs) {
            _a[0] += rhs[0];
            _a[1] += rhs[1];
            _a[2] += rhs[2];
            _a[3] += rhs[3];
            return *this;
        }

        Vector4<T> & operator -= (const T rhs) {
            _a[0] -= rhs;
            _a[1] -= rhs;
            _a[2] -= rhs;
            _a[3] -= rhs;
            return *this;
        }

        Vector4<T> & operator -= (const Vector4<T> & rhs) {
            _a[0] -= rhs[0];
            _a[1] -= rhs[1];
            _a[2] -= rhs[2];
            _a[3] -= rhs[3];
            return *this;
        }

        Vector4<T> & operator / (const T rhs) const {
            Vector4<T> r(*this);
            return r /= rhs;
        }

        Vector4<T> & operator / (const Vector4<T> & rhs)  const {
            Vector4<T> r(*this);
            return r /= rhs;
        }

        Vector4<T> & operator * (const T rhs) const {
            Vector4<T> r(*this);
            return r *= rhs;
        }

        Vector4<T> & operator * (const Vector4<T> & rhs) const {
            Vector4<T> r(*this);
            return r *= rhs;
        }

        Vector4<T> & operator + (const T rhs) const {
            Vector4<T> r(*this);
            return r *= rhs;
        }

        Vector4<T> & operator + (const Vector4<T> & rhs) const {
            Vector4<T> r(*this);
            return r += rhs;
        }

        Vector4<T> & operator - (const T rhs) const {
            Vector4<T> r(*this);
            return r -= rhs;
        }

        Vector4<T> & operator - (const Vector4<T> & rhs) const {
            Vector4<T> r(*this);
            return r -= rhs;
        }
    };

    template <typename T>
    std::ostream & operator << (std::ostream & s, const Vector4<T> & rhs) {
        s << '(' << rhs[0] << ", ";
        s << rhs[1] << ", ";
        s << rhs[2] << ", ";
        s << rhs[3] << ')';
        return s;
    }

    template <typename T>
    std::istream & operator >> (std::istream & s, Vector4<T> & rhs)	{
        s >> rhs[0];
        s >> rhs[1];
        s >> rhs[2];
        s >> rhs[3];
        return s;
    }

    template <typename T>
    const Vector4<T> Vector4<T>::Zero(T(0), T(0), T(0), T(0));

    template <typename T>
    const Vector4<T> Vector4<T>::One(T(1), T(1), T(1), T(1));

    template <typename T>
    const Vector4<T> Vector4<T>::UnitX(T(1), T(0), T(0), T(0));

    template <typename T>
    const Vector4<T> Vector4<T>::UnitY(T(0), T(1), T(0), T(0));

    template <typename T>
    const Vector4<T> Vector4<T>::UnitZ(T(0), T(0), T(1), T(0));

    template <typename T>
    const Vector4<T> Vector4<T>::UnitW(T(0), T(0), T(0), T(1));

    typedef Vector4<float> Vector4f;
    typedef Vector4<double> Vector4d;
}

Refactorings

No refactoring yet !

34db50b7ce2e115afadf5a765b950739

Thomas Salvador

November 14, 2009, November 14, 2009 23:52, permalink

2 ratings. Login to rate!

hello.

i suggest you to implement a generic VectorX for arbitary long vectors. most operations would loop over this length l and handle the components. like:

for(i=0;i<l;i++) { _a[i] += rhs[i]; }

then create subclasses of VectorX for the required lengths Vector2 .. Vector4 and just set the length in their constructors. i.e. Vector2 inherits the complete functionality and just configures VectorX to process 2-component vectors.

you could check for compatibility of the parameters by checking their number of components.

regards,
thomas.

F9a9ba6663645458aa8630157ed5e71e

Ants

November 17, 2009, November 17, 2009 10:15, permalink

1 rating. Login to rate!

Why are your division operators guarding for division by zero? Don't you want an exception to be thrown if you are dividing by zero and catch the error early, instead of masking it and getting weird results? If you really want to mask the division by zero, then you should also add the same kind of guard in the Normalize() methods.

73465ace35a83efec10235c119800304

vodkamilkshake

December 8, 2011, December 08, 2011 23:18, permalink

No rating. Login to rate!

Why not use Boost.Operators for comparison operators?

73465ace35a83efec10235c119800304

vodkamilkshake

December 8, 2011, December 08, 2011 23:25, permalink

No rating. Login to rate!

Why not use Boost.Operators for comparison operators?

Your refactoring





Format Copy from initial code

or Cancel