utility: generic vector
Changed old 2d vector template to a generic vector class that can have any amount of dimensions. Added implementations for 2d and 4d and typedefs for int and float. Updated the unit tests accordingly fortune cookie message = pray for what you want but work for the things you need
This commit is contained in:
@@ -37,6 +37,8 @@ add_definitions(${CLANG_DEFINITIONS})
|
||||
|
||||
# Boost ------------------------------------------------------------------------
|
||||
|
||||
message("quatsch")
|
||||
|
||||
set(BOOST_ROOT $ENV{BOOST_155_DIR})
|
||||
set(Boost_USE_MULTITHREAD ON)
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
@@ -44,6 +46,10 @@ set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
set(BOOST_LIBRARYDIR $ENV{BOOST_155_DIR})
|
||||
find_package( Boost 1.55 COMPONENTS system filesystem REQUIRED )
|
||||
|
||||
message("${BOOST_LIBRARYDIR}")
|
||||
|
||||
message("quatsch")
|
||||
|
||||
# Lib --------------------------------------------------------------------------
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/lib)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Graph.cpp removeEdge() ERROR: Can't remove member edge, without removing the child node.
|
||||
TextAccess.cpp checkIndexIntervalInRange() WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 2 > 1
|
||||
TextAccess.cpp checkIndexInRange() WARNING: Tried to access index 9. Maximum index is 7
|
||||
TextAccess.cpp checkIndexInRange() WARNING: Tried to access index 9. Maximum index is 7
|
||||
TextAccess.cpp getLine() WARNING: Line numbers start with one, is 0
|
||||
TextAccess.cpp getLines() WARNING: Line numbers start with one, is 0
|
||||
Graph.cpp Graph::removeEdge() ERROR: Can't remove member edge, without removing the child node.
|
||||
TextAccess.cpp TextAccess::checkIndexIntervalInRange() WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 2 > 1
|
||||
TextAccess.cpp TextAccess::checkIndexInRange() WARNING: Tried to access index 9. Maximum index is 7
|
||||
TextAccess.cpp TextAccess::checkIndexInRange() WARNING: Tried to access index 9. Maximum index is 7
|
||||
TextAccess.cpp TextAccess::getLine() WARNING: Line numbers start with one, is 0
|
||||
TextAccess.cpp TextAccess::getLines() WARNING: Line numbers start with one, is 0
|
||||
|
||||
@@ -112,6 +112,7 @@ add_files(
|
||||
utility/math/Color.h
|
||||
utility/math/Vector2.h
|
||||
utility/math/Vector4.h
|
||||
utility/math/VectorBase.h
|
||||
|
||||
utility/messaging/Message.h
|
||||
utility/messaging/MessageBase.h
|
||||
@@ -127,6 +128,7 @@ add_files(
|
||||
utility/ConfigManager.h
|
||||
utility/FileSystem.cpp
|
||||
utility/FileSystem.h
|
||||
utility/Property.h
|
||||
utility/types.h
|
||||
utility/utilityString.cpp
|
||||
utility/utilityString.h
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef PROPERTY_H
|
||||
#define PROPERTY_H
|
||||
|
||||
template<class T>
|
||||
class Property
|
||||
{
|
||||
public:
|
||||
Property(T* valuePointer);
|
||||
~Property();
|
||||
|
||||
T& operator=(const T& value);
|
||||
|
||||
operator const T&() const;
|
||||
|
||||
private:
|
||||
T* m_valuePointer;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Property<T>::Property(T* valuePointer)
|
||||
: m_valuePointer(valuePointer)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Property<T>::~Property()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& Property<T>::operator=(const T& value)
|
||||
{
|
||||
*m_valuePointer = value;
|
||||
return *m_valuePointer;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Property<T>::operator const T&() const
|
||||
{
|
||||
return *m_valuePointer;
|
||||
}
|
||||
|
||||
#endif // PROPERTY_H
|
||||
+73
-163
@@ -1,69 +1,64 @@
|
||||
#ifndef VECTOR_2_H
|
||||
#define VECTOR_2_H
|
||||
|
||||
#include <cmath>
|
||||
#include <ostream>
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/Property.h"
|
||||
|
||||
#include "VectorBase.h"
|
||||
|
||||
template<class T>
|
||||
class Vector2
|
||||
class Vector2 : public VectorBase<T, 2>
|
||||
{
|
||||
public:
|
||||
Vector2();
|
||||
Vector2(const T x, const T y);
|
||||
Vector2(const Vector2<T>& vector);
|
||||
~Vector2();
|
||||
Vector2(const T& x, const T& y);
|
||||
Vector2(const VectorBase<T, 2>& vector);
|
||||
virtual ~Vector2();
|
||||
|
||||
float getLengthSquared() const;
|
||||
float getLength() const;
|
||||
T getValue(const unsigned int index) const;
|
||||
void setValue(const unsigned int index, const T& value);
|
||||
|
||||
T& operator[](const unsigned int index);
|
||||
|
||||
Property<T> x;
|
||||
Property<T> y;
|
||||
|
||||
Vector2<T> normalize();
|
||||
Vector2<T> normalized() const;
|
||||
|
||||
// checks whether all values are the same
|
||||
bool isEqual(const Vector2<T>& other) const;
|
||||
// checks if the memory address is the same
|
||||
bool isSame(const Vector2<T>& other) const;
|
||||
template<class U>
|
||||
void operator=(Vector2<U>& other);
|
||||
|
||||
void operator=(Vector2<T>& other);
|
||||
|
||||
Vector2<T> operator+(const Vector2<T>& other) const;
|
||||
Vector2<T> operator-(const Vector2<T>& other) const;
|
||||
Vector2<T> operator*(const T scalar) const;
|
||||
T operator*(const Vector2<T>& other) const;
|
||||
Vector2<T> operator/(const T scalar) const;
|
||||
|
||||
Vector2<T> operator+=(const Vector2<T>& other);
|
||||
Vector2<T> operator-=(const Vector2<T>& other);
|
||||
Vector2<T> operator*=(const T scalar);
|
||||
Vector2<T> operator/=(const T scalar);
|
||||
|
||||
// checks whether all values are the same
|
||||
bool operator==(const Vector2<T>& other) const;
|
||||
// checks whether at least one value is different
|
||||
bool operator!=(const Vector2<T>& other) const;
|
||||
|
||||
T x;
|
||||
T y;
|
||||
protected:
|
||||
static const unsigned int m_xIndex = 0;
|
||||
static const unsigned int m_yIndex = 1;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Vector2<T>::Vector2()
|
||||
: x(0)
|
||||
, y(0)
|
||||
: VectorBase<T, 2>()
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
{
|
||||
setValue(m_xIndex, 0);
|
||||
setValue(m_yIndex, 0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T>::Vector2(const T x, const T y)
|
||||
: x(x)
|
||||
, y(y)
|
||||
Vector2<T>::Vector2(const T& x, const T& y)
|
||||
: VectorBase<T, 2>()
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
{
|
||||
setValue(m_xIndex, x);
|
||||
setValue(m_yIndex, y);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T>::Vector2(const Vector2<T> &vector)
|
||||
: x(vector.x)
|
||||
, y(vector.y)
|
||||
Vector2<T>::Vector2(const VectorBase<T, 2>& vector)
|
||||
: VectorBase<T, 2>(vector)
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
{
|
||||
}
|
||||
|
||||
@@ -73,148 +68,63 @@ Vector2<T>::~Vector2()
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float Vector2<T>::getLengthSquared() const
|
||||
T Vector2<T>::getValue(const unsigned int index) const
|
||||
{
|
||||
return static_cast<float>(x * x) + static_cast<float>(y * y);
|
||||
try
|
||||
{
|
||||
return VectorBase<T, 2>::getValue(index);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float Vector2<T>::getLength() const
|
||||
void Vector2<T>::setValue(const unsigned int index, const T& value)
|
||||
{
|
||||
return std::sqrt(getLengthSquared());
|
||||
try
|
||||
{
|
||||
VectorBase<T, 2>::setValue(index, value);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& Vector2<T>::operator[](const unsigned int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
return VectorBase<T, 2>::[index];
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::normalize()
|
||||
{
|
||||
float length = getLength();
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
|
||||
return *this;
|
||||
return VectorBase<T, 2>::normalize();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::normalized() const
|
||||
{
|
||||
float length = getLength();
|
||||
|
||||
return Vector2<T>(static_cast<float>(x) / length, static_cast<float>(y) / length);
|
||||
return VectorBase<T, 2>::normalized();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Vector2<T>::isEqual(const Vector2<T>& other) const
|
||||
template<class U>
|
||||
void Vector2<T>::operator=(Vector2<U>& other)
|
||||
{
|
||||
return ((x == other.x) && (y == other.y));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Vector2<T>::isSame(const Vector2<T>& other) const
|
||||
{
|
||||
return &other == this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector2<T>::operator=(Vector2<T>& other)
|
||||
{
|
||||
if (isSame(other) || isEqual(other))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator+(const Vector2<T>& other) const
|
||||
{
|
||||
Vector2<T> result(*this);
|
||||
return (result += other);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator-(const Vector2<T>& other) const
|
||||
{
|
||||
Vector2<T> result(*this);
|
||||
return (result -= other);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator*(const T scalar) const
|
||||
{
|
||||
Vector2<T> result(*this);
|
||||
return (result *= scalar);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T Vector2<T>::operator*(const Vector2<T>& other) const
|
||||
{
|
||||
return x * other.x + y * other.y;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator/(const T scalar) const
|
||||
{
|
||||
Vector2<T> result(*this);
|
||||
return (result /= scalar);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator+=(const Vector2<T>& other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator-=(const Vector2<T>& other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator*=(const T scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector2<T> Vector2<T>::operator/=(const T scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Vector2<T>::operator==(const Vector2<T>& other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Vector2<T>::operator!=(const Vector2<T>& other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
std::ostream& operator<<(std::ostream& ostream, const Vector2<T>& vector)
|
||||
{
|
||||
ostream << "[" << vector.x << ", " << vector.y << "]";
|
||||
return ostream;
|
||||
this->assign(other);
|
||||
}
|
||||
|
||||
typedef Vector2<float> Vec2f;
|
||||
|
||||
+129
-14
@@ -1,32 +1,147 @@
|
||||
#ifndef VECTOR_4_H
|
||||
#define VECTOR_4_H
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/Property.h"
|
||||
|
||||
#include "VectorBase.h"
|
||||
|
||||
template<class T>
|
||||
class Vector4
|
||||
class Vector4 : public VectorBase<T, 4>
|
||||
{
|
||||
public:
|
||||
Vector4();
|
||||
Vector4(T x, T y, T z, T w);
|
||||
Vector4(const T& x, const T& y, const T& z, const T& w);
|
||||
Vector4(const VectorBase<T, 2>& vector);
|
||||
virtual ~Vector4();
|
||||
|
||||
T x, y, z, w;
|
||||
T getValue(const unsigned int index) const;
|
||||
void setValue(const unsigned int index, const T& value);
|
||||
|
||||
T& operator[](const unsigned int index);
|
||||
|
||||
Property<T> x;
|
||||
Property<T> y;
|
||||
Property<T> z;
|
||||
Property<T> w;
|
||||
|
||||
Vector4<T> normalize();
|
||||
Vector4<T> normalized() const;
|
||||
|
||||
template<class U>
|
||||
void operator=(Vector4<U>& other);
|
||||
|
||||
protected:
|
||||
static const unsigned int m_xIndex = 0;
|
||||
static const unsigned int m_yIndex = 1;
|
||||
static const unsigned int m_zIndex = 2;
|
||||
static const unsigned int m_wIndex = 3;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Vector4<T>::Vector4()
|
||||
: x(0)
|
||||
, y(0)
|
||||
, z(0)
|
||||
, w(0)
|
||||
{}
|
||||
: VectorBase<T, 4>()
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
, z(&m_values[m_zIndex])
|
||||
, w(&m_values[m_wIndex])
|
||||
{
|
||||
setValue(m_xIndex, 0);
|
||||
setValue(m_yIndex, 0);
|
||||
setValue(m_zIndex, 0);
|
||||
setValue(m_wIndex, 0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector4<T>::Vector4(T x, T y, T z, T w)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, z(z)
|
||||
, w(w)
|
||||
{}
|
||||
Vector4<T>::Vector4(const T& x, const T& y, const T& z, const T& w)
|
||||
: VectorBase<T, 4>()
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
, z(&m_values[m_zIndex])
|
||||
, w(&m_values[m_wIndex])
|
||||
{
|
||||
setValue(m_xIndex, x);
|
||||
setValue(m_yIndex, y);
|
||||
setValue(m_zIndex, z);
|
||||
setValue(m_wIndex, w);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector4<T>::Vector4(const VectorBase<T, 4>& vector)
|
||||
: VectorBase<T, 4>(vector)
|
||||
, x(&m_values[m_xIndex])
|
||||
, y(&m_values[m_yIndex])
|
||||
, z(&m_values[m_zIndex])
|
||||
, w(&m_values[m_wIndex])
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector4<T>::~Vector4()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T Vector4<T>::getValue(const unsigned int index) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return VectorBase<T, 4>::getValue(index);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector4<T>::setValue(const unsigned int index, const T& value)
|
||||
{
|
||||
try
|
||||
{
|
||||
VectorBase<T, 4>::setValue(index, value);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& Vector4<T>::operator[](const unsigned int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
return VectorBase<T, 4>::[index];
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector4<T> Vector4<T>::normalize()
|
||||
{
|
||||
return VectorBase<T, 4>::normalize();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector4<T> Vector4<T>::normalized() const
|
||||
{
|
||||
return VectorBase<T, 4>::normalized();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class U>
|
||||
void Vector4<T>::operator=(Vector4<U>& other)
|
||||
{
|
||||
this->assign(other);
|
||||
}
|
||||
|
||||
typedef Vector4<float> Vec4f;
|
||||
typedef Vector4<int> Vec4i;
|
||||
|
||||
#endif // VECTOR_4_H
|
||||
|
||||
@@ -0,0 +1,452 @@
|
||||
#ifndef VECTOR_BASE_H
|
||||
#define VECTOR_BASE_H
|
||||
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#define VECTOR_CHECK_INDEX(idx) \
|
||||
do \
|
||||
{ \
|
||||
unsigned int i((idx)); \
|
||||
checkIndexInRange(i, __FUNCTION__); \
|
||||
} \
|
||||
while(0) \
|
||||
|
||||
|
||||
template<class T, unsigned int N>
|
||||
class VectorBase
|
||||
{
|
||||
public:
|
||||
VectorBase();
|
||||
VectorBase(const T values[N]);
|
||||
VectorBase(const VectorBase<T, N>& vector);
|
||||
~VectorBase();
|
||||
|
||||
T getValue(const unsigned int index) const;
|
||||
void setValue(const unsigned int index, const T& value);
|
||||
|
||||
unsigned int getDimensions() const;
|
||||
|
||||
float getLengthSquared() const;
|
||||
float getLength() const;
|
||||
|
||||
VectorBase<T, N> normalize();
|
||||
VectorBase<T, N> normalized() const;
|
||||
|
||||
template<class U>
|
||||
void assign(const VectorBase<U, N>& other);
|
||||
|
||||
template<class U>
|
||||
VectorBase<T, N> add(const VectorBase<U, N>& other);
|
||||
template<class U>
|
||||
VectorBase<T, N> subtract(const VectorBase<U, N>& other);
|
||||
template<class U>
|
||||
VectorBase<T, N> scalarMultiplication(const U& scalar);
|
||||
template<class U>
|
||||
T dotProduct(const VectorBase<U, N>& other);
|
||||
|
||||
// checks whether all values are the same
|
||||
template<class U>
|
||||
bool isEqual(const VectorBase<U, N>& other) const;
|
||||
// checks whether it really is the same object (at one and the same memory address)
|
||||
template<class U>
|
||||
bool isSame(const VectorBase<U, N>& other) const;
|
||||
|
||||
T& operator[](const unsigned int index);
|
||||
|
||||
template<class U>
|
||||
void operator=(VectorBase<U, N>& other);
|
||||
|
||||
template<class U>
|
||||
VectorBase<T, N> operator+(const VectorBase<U, N>& other) const;
|
||||
template<class U>
|
||||
VectorBase<T, N> operator-(const VectorBase<U, N>& other) const;
|
||||
template<class U>
|
||||
VectorBase<T, N> operator*(const U& scalar) const;
|
||||
/*template<class U>
|
||||
T operator*(const VectorBase<U, N>& other) const;*/
|
||||
template<class U>
|
||||
VectorBase<T, N> operator/(const U& scalar) const;
|
||||
|
||||
template<class U>
|
||||
VectorBase<T, N> operator+=(const VectorBase<U, N>& other);
|
||||
template<class U>
|
||||
VectorBase<T, N> operator-=(const VectorBase<U, N>& other);
|
||||
template<class U>
|
||||
VectorBase<T, N> operator*=(const U& scalar);
|
||||
template<class U>
|
||||
VectorBase<T, N> operator/=(const U& scalar);
|
||||
|
||||
// checks whether all values are the same
|
||||
template<class U>
|
||||
bool operator==(const VectorBase<U, N>& other) const;
|
||||
// checks whether at least one value is different
|
||||
template<class U>
|
||||
bool operator!=(const VectorBase<U, N>& other) const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
protected:
|
||||
T m_values[N];
|
||||
|
||||
private:
|
||||
inline void checkIndexInRange(unsigned int index, const std::string& function) const
|
||||
{
|
||||
if(index >= m_dimensions)
|
||||
{
|
||||
std::stringstream message;
|
||||
message << function << ": index " << index << " is out of range, maximum is " << m_dimensions-1;
|
||||
throw(std::exception(message.str().c_str()));
|
||||
}
|
||||
}
|
||||
inline void setValues(const T values[N])
|
||||
{
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
m_values[i] = values[i];
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int m_dimensions;
|
||||
};
|
||||
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N>::VectorBase():
|
||||
m_dimensions(N)
|
||||
{}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N>::VectorBase(const T values[N]):
|
||||
m_dimensions(N)
|
||||
{
|
||||
setValues(values);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N>::VectorBase(const VectorBase<T, N>& vector):
|
||||
m_dimensions(vector.m_dimensions)
|
||||
{
|
||||
setValues(vector.m_values);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N>::~VectorBase()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
T VectorBase<T, N>::getValue(const unsigned int index) const
|
||||
{
|
||||
VECTOR_CHECK_INDEX(index);
|
||||
|
||||
return m_values[index];
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
void VectorBase<T, N>::setValue(const unsigned int index, const T& value)
|
||||
{
|
||||
VECTOR_CHECK_INDEX(index);
|
||||
|
||||
m_values[index] = value;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
unsigned int VectorBase<T, N>::getDimensions() const
|
||||
{
|
||||
return m_dimensions;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
float VectorBase<T, N>::getLengthSquared() const
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
result += float(m_values[i] * m_values[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
float VectorBase<T, N>::getLength() const
|
||||
{
|
||||
return std::sqrt(getLengthSquared());
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N> VectorBase<T, N>::normalize()
|
||||
{
|
||||
float length = getLength();
|
||||
|
||||
if (length > 0.0f)
|
||||
{
|
||||
T tmpValues[N];
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = m_values[i] / length;
|
||||
}
|
||||
|
||||
//the values of *this won't be changed until all are in a valid state
|
||||
setValues(tmpValues);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
VectorBase<T, N> VectorBase<T, N>::normalized() const
|
||||
{
|
||||
float length = getLength();
|
||||
|
||||
T tmpValues[N];
|
||||
|
||||
if (length > 0.0f)
|
||||
{
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = m_values[i] / length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return VectorBase<T, N>(tmpValues);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
void VectorBase<T, N>::assign(const VectorBase<U, N>& other)
|
||||
{
|
||||
if(isSame(other))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(isEqual(other))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setValues(other.m_values);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::add(const VectorBase<U, N>& other)
|
||||
{
|
||||
T tmpValues[N];
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = m_values[i] + other.m_values[i];
|
||||
}
|
||||
|
||||
//the values of *this won't be changed until all are in a valid state
|
||||
setValues(tmpValues);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::subtract(const VectorBase<U, N>& other)
|
||||
{
|
||||
T tmpValues[N];
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = m_values[i] - other.m_values[i];
|
||||
}
|
||||
|
||||
//the values of *this won't be changed until all are in a valid state
|
||||
setValues(tmpValues);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::scalarMultiplication(const U& scalar)
|
||||
{
|
||||
T tmpValues[N];
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
tmpValues[i] = m_values[i] * scalar;
|
||||
}
|
||||
|
||||
//the values of *this won't be changed until all are in a valid state
|
||||
setValues(tmpValues);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
T VectorBase<T, N>::dotProduct(const VectorBase<U, N>& other)
|
||||
{
|
||||
T result = 0.0f;
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
result += (m_values[i]*other.m_values[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
bool VectorBase<T, N>::isEqual(const VectorBase<U, N>& other) const
|
||||
{
|
||||
if(m_dimensions != other.m_dimensions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < m_dimensions; i++)
|
||||
{
|
||||
if(m_values[i] != other.m_values[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
bool VectorBase<T, N>::isSame(const VectorBase<U, N>& other) const
|
||||
{
|
||||
return &other == this;
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
T& VectorBase<T, N>::operator[](const unsigned int index)
|
||||
{
|
||||
VECTOR_CHECK_INDEX(index);
|
||||
|
||||
return m_values[index];
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
void VectorBase<T, N>::operator=(VectorBase<U, N>& other)
|
||||
{
|
||||
assign(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator+(const VectorBase<U, N>& other) const
|
||||
{
|
||||
VectorBase<T, N> result(*this);
|
||||
return result.add(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator-(const VectorBase<U, N>& other) const
|
||||
{
|
||||
VectorBase<T, N> result(*this);
|
||||
return result.subtract(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator*(const U& scalar) const
|
||||
{
|
||||
VectorBase<T, N> result(*this);
|
||||
return result.scalarMultiplication(scalar);
|
||||
}
|
||||
|
||||
//template<class T, unsigned int N>
|
||||
//template<class U>
|
||||
//T VectorBase<T, N>::operator*(const VectorBase<U, N>& other) const
|
||||
//{
|
||||
// return dotProduct(other);
|
||||
//}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator/(const U& scalar) const
|
||||
{
|
||||
VectorBase<T, N> result(*this);
|
||||
return result.scalarMultiplication(1.0f/scalar);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator+=(const VectorBase<U, N>& other)
|
||||
{
|
||||
return add(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator-=(const VectorBase<U, N>& other)
|
||||
{
|
||||
return subtract(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator*=(const U& scalar)
|
||||
{
|
||||
return scalarMultiplication(scalar);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
VectorBase<T, N> VectorBase<T, N>::operator/=(const U& scalar)
|
||||
{
|
||||
return scalarMultiplication(1.0f/scalar);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
bool VectorBase<T, N>::operator==(const VectorBase<U, N>& other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
template<class U>
|
||||
bool VectorBase<T, N>::operator!=(const VectorBase<U, N>& other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
std::string VectorBase<T, N>::toString() const
|
||||
{
|
||||
std::stringstream result;
|
||||
result << "[";
|
||||
|
||||
for(unsigned int i = 0; i < m_dimensions-1; i++)
|
||||
{
|
||||
result << m_values[i] << ", ";
|
||||
}
|
||||
result << m_values[m_dimensions-1] << "]";
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
template<class T, unsigned int N>
|
||||
std::ostream& operator<<(std::ostream& ostream, const VectorBase<T, N>& vector)
|
||||
{
|
||||
/*for(unsigned int i = 0; i < vector.getDimensions()-1; i++)
|
||||
{
|
||||
ostream << vector.getValue(i) << ", ";
|
||||
}
|
||||
ostream << vector.getValue(vector.getDimensions()-1);*/
|
||||
|
||||
ostream << vector.toString();
|
||||
|
||||
return ostream;
|
||||
}
|
||||
|
||||
#endif // VECTOR_BASE_H
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
class Vector2TestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
@@ -197,10 +199,15 @@ public:
|
||||
TS_ASSERT_EQUALS(84.0f, vec0.y);
|
||||
|
||||
Vec2i vec2(-2, 2);
|
||||
Vec2i vec3 = vec2 * float(42.5f);
|
||||
Vec2i vec3 = vec2 * 42.4f;
|
||||
|
||||
TS_ASSERT_EQUALS(-84, vec3.x);
|
||||
TS_ASSERT_EQUALS(84, vec3.y);
|
||||
TS_ASSERT_EQUALS(-84, (int)vec3.x);
|
||||
TS_ASSERT_EQUALS(84, (int)vec3.y);
|
||||
|
||||
Vec2i vec3b = vec2 * 42.5f;
|
||||
|
||||
TS_ASSERT_EQUALS(-85, (int)vec3b.x);
|
||||
TS_ASSERT_EQUALS(85, (int)vec3b.y);
|
||||
|
||||
TS_ASSERT_EQUALS(-2, vec2.x);
|
||||
TS_ASSERT_EQUALS(2, vec2.y);
|
||||
@@ -208,6 +215,10 @@ public:
|
||||
vec2 *= 42;
|
||||
TS_ASSERT_EQUALS(-84, vec2.x);
|
||||
TS_ASSERT_EQUALS(84, vec2.y);
|
||||
|
||||
vec2 *= 0.5f;
|
||||
TS_ASSERT_EQUALS(-42, vec2.x);
|
||||
TS_ASSERT_EQUALS(42, vec2.y);
|
||||
}
|
||||
|
||||
void test_dot_product_operator()
|
||||
@@ -216,15 +227,15 @@ public:
|
||||
Vec2f vec1(3.0f, 6.0f);
|
||||
Vec2f vec2(-2.0f, -1.0f);
|
||||
|
||||
TS_ASSERT_EQUALS(30.0f, vec0*vec1);
|
||||
TS_ASSERT_EQUALS(-8.0f, vec0*vec2);
|
||||
TS_ASSERT_EQUALS(30.0f, vec0.dotProduct(vec1));
|
||||
TS_ASSERT_EQUALS(-8.0f, vec0.dotProduct(vec2));
|
||||
|
||||
Vec2f vec3(2, 4);
|
||||
Vec2f vec4(3, 6);
|
||||
Vec2f vec5(-2, -1);
|
||||
|
||||
TS_ASSERT_EQUALS(30, vec3 * vec4);
|
||||
TS_ASSERT_EQUALS(-8, vec3 * vec5);
|
||||
TS_ASSERT_EQUALS(30, vec3.dotProduct(vec4));
|
||||
TS_ASSERT_EQUALS(-8, vec3.dotProduct(vec5));
|
||||
}
|
||||
|
||||
void test_scalar_division_operators()
|
||||
|
||||
Reference in New Issue
Block a user