/*
* =====================================================================================
*
* Filename: jMatrix.h
*
* Description: Various matrix classes
*
* Version: 1.0
* Created: 31/05/2011 22:00:42
* Revision: none
* Compiler: gcc
*
* Author: John Ryland (jryland), jryland@xiaofrog.com
* Company: InvertedLogic
*
* =====================================================================================
*/
#ifndef __J_MATRIX_H__
#define __J_MATRIX_H__
#include <jTypes.h>
#include <jMath.h>
#include <stdlib.h>
#include <string.h>
template <typename T, size_t dimensions>
class jVector
{
public:
/// default constructor
jVector();
/// copy construtor
jVector(const jVector<T, dimensions>& a_vector);
/// comparison operators
bool operator==(const jVector<T, dimensions> &a_vector) const;
bool operator!=(const jVector<T, dimensions> &a_vector) const;
/// assignment operator
jVector<T, dimensions>& operator =(const jVector<T, dimensions>& a_vector);
/// operators with objects of the same type
jVector<T, dimensions>& operator+=(const jVector<T, dimensions>& a_vector);
jVector<T, dimensions>& operator-=(const jVector<T, dimensions>& a_vector);
jVector<T, dimensions>& operator*=(const jVector<T, dimensions>& a_vector);
jVector<T, dimensions>& operator/=(const jVector<T, dimensions>& a_vector);
const jVector<T, dimensions> operator+(const jVector<T, dimensions> &a_vector) const;
const jVector<T, dimensions> operator-(const jVector<T, dimensions> &a_vector) const;
const jVector<T, dimensions> operator*(const jVector<T, dimensions> &a_vector) const;
const jVector<T, dimensions> operator/(const jVector<T, dimensions> &a_vector) const;
/// operators with objects of the type of the components
jVector<T, dimensions>& operator+=(const T& a_val);
jVector<T, dimensions>& operator-=(const T& a_val);
jVector<T, dimensions>& operator*=(const T& a_val);
jVector<T, dimensions>& operator/=(const T& a_val);
const jVector<T, dimensions> operator+(const T &a_val) const;
const jVector<T, dimensions> operator-(const T &a_val) const;
const jVector<T, dimensions> operator*(const T &a_val) const;
const jVector<T, dimensions> operator/(const T &a_val) const;
T sumComponents() const;
T dotProduct(const jVector<T, dimensions> &a_vector) const;
T length() const;
void normalize();
jVector<T, dimensions>& normalized() const;
T components[dimensions];
};
typedef jVector<jInt32,2> jVector2i;
typedef jVector<jFloat32,3> jVector3f;
typedef jVector<jVector3f,3> jMatrix3x3f;
template <typename T, size_t dimensions>
inline jVector<T, dimensions>::jVector()
{
memset(components, 0, sizeof(T)*dimensions);
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>::jVector(const jVector<T, dimensions>& a_vector)
{
*this = a_vector;
/*
m_x = a_vector.m_x;
m_y = a_vector.m_y;
m_z = a_vector.m_z;
*/
}
template <typename T, size_t dimensions>
inline bool jVector<T, dimensions>::operator==(const jVector<T, dimensions> &a_vector) const
{
for (unsigned int i = 0; i < dimensions; i++)
{
if ( components[i] != a_vector.components[i] )
{
return false;
}
}
return true;
}
template <typename T, size_t dimensions>
inline bool jVector<T, dimensions>::operator!=(const jVector<T, dimensions> &a_vector) const
{
return !(*this == a_vector);
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator=(const jVector<T, dimensions>& a_vector)
{
// don't do assignment if same object
if (this != &a_vector)
{
// Deallocate, allocate new space, copy values...
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] = a_vector.components[i];
}
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator+=(const jVector<T, dimensions>& a_vector)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] += a_vector.components[i];
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator-=(const jVector<T, dimensions>& a_vector)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] -= a_vector.components[i];
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator*=(const jVector<T, dimensions>& a_vector)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] *= a_vector.components[i];
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator/=(const jVector<T, dimensions>& a_vector)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] /= a_vector.components[i];
}
return *this;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator+(const jVector<T, dimensions> &a_vector) const
{
return jVector<T, dimensions>(*this) += a_vector;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator-(const jVector<T, dimensions> &a_vector) const
{
return jVector<T, dimensions>(*this) -= a_vector;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator*(const jVector<T, dimensions> &a_vector) const
{
return jVector<T, dimensions>(*this) *= a_vector;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator/(const jVector<T, dimensions> &a_vector) const
{
return jVector<T, dimensions>(*this) /= a_vector;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator+=(const T& a_val)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] += a_val;
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator-=(const T& a_val)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] -= a_val;
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator*=(const T& a_val)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] *= a_val;
}
return *this;
}
template <typename T, size_t dimensions>
inline jVector<T, dimensions>& jVector<T, dimensions>::operator/=(const T& a_val)
{
for (unsigned int i = 0; i < dimensions; i++)
{
components[i] /= a_val;
}
return *this;
}
// Specialization for jVector3f. Would prefer this could be a specialization
// for any dimensions when T is a float
template <>
inline jVector3f& jVector3f::operator/=(const jFloat32& a_val)
{
jFloat32 one_over_val = 1.0f / a_val;
for (unsigned int i = 0; i < 3; i++)
{
components[i] *= one_over_val;
}
return *this;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator+(const T &a_val) const
{
return jVector<T, dimensions>(*this) += a_val;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator-(const T &a_val) const
{
return jVector<T, dimensions>(*this) -= a_val;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator*(const T &a_val) const
{
return jVector<T, dimensions>(*this) *= a_val;
}
template <typename T, size_t dimensions>
inline const jVector<T, dimensions> jVector<T, dimensions>::operator/(const T &a_val) const
{
return jVector<T, dimensions>(*this) /= a_val;
}
template <typename T, size_t dimensions>
inline T jVector<T, dimensions>::sumComponents() const
{
T sum;
for (unsigned int i = 0; i < dimensions; i++)
{
sum += components[i];
}
return sum;
}
template <typename T, size_t dimensions>
inline T jVector<T, dimensions>::dotProduct(const jVector<T, dimensions> &a_vector) const
{
jVector<T, dimensions> vec;
vec = *this * a_vector;
return vec.sumComponents();
}
template <typename T, size_t dimensions>
inline T jVector<T, dimensions>::length() const
{
return jMath<T>::squareRoot(dotProduct(*this));
}
template <typename T, size_t dimensions>
void jVector<T, dimensions>::normalize()
{
jVector<T, dimensions>(*this) /= length();
}
template <typename T, size_t dimensions>
jVector<T, dimensions>& jVector<T, dimensions>::normalized() const
{
return jVector<T, dimensions>(*this) /= length();
}
#endif // __J_VECTOR_H__