Utility: Vector2

2d template vector (with typedefs for int and float)

review id = 5
This commit is contained in:
Manuel Dobusch
2014-04-24 14:06:45 +02:00
parent 879373a22f
commit 651f0f68a2
4 changed files with 484 additions and 0 deletions
+2
View File
@@ -67,6 +67,8 @@ add_files(
utility/logging/LogManager.h
utility/logging/LogMessage.h
utility/math/Vector2.h
utility/ConfigManager.cpp
utility/ConfigManager.h
+222
View File
@@ -0,0 +1,222 @@
#ifndef VECTOR_2_H
#define VECTOR_2_H
#include <math.h>
template<class T>
class Vector2
{
public:
Vector2();
Vector2(const T x, const T y);
Vector2(const Vector2<T>& vector);
~Vector2();
float getLengthSquared() const;
float getLength() const;
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;
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;
};
template<class T>
Vector2<T>::Vector2()
: x(0)
, y(0)
{
}
template<class T>
Vector2<T>::Vector2(const T x, const T y)
: x(x)
, y(y)
{
}
template<class T>
Vector2<T>::Vector2(const Vector2<T> &vector)
: x(vector.x)
, y(vector.y)
{
}
template<class T>
Vector2<T>::~Vector2()
{
}
template<class T>
float Vector2<T>::getLengthSquared() const
{
return (x * x) + (y * y);
}
template<class T>
float Vector2<T>::getLength() const
{
return std::sqrt(getLengthSquared());
}
template<class T>
Vector2<T> Vector2<T>::normalize()
{
float length = getLength();
static_cast<float>(x) /= length;
static_cast<float>(y) /= length;
return *this;
}
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);
}
template<class T>
bool Vector2<T>::isEqual(const Vector2<T>& other) const
{
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;
}
typedef Vector2<float> Vec2f;
typedef Vector2<int> Vec2i;
#endif // VECTOR_2_H
+1
View File
@@ -4,4 +4,5 @@ add_files(
ConfigManagerTestSuite.h
LogManagerTestSuite.h
UtilityTestSuite.h
Vector2TestSuite.h
)
+259
View File
@@ -0,0 +1,259 @@
#include "cxxtest/TestSuite.h"
#include "utility/math/Vector2.h"
class Vector2TestSuite : public CxxTest::TestSuite
{
public:
void test_vec2i_constructors()
{
Vec2i vec0;
Vec2i vec1(1, 1);
Vec2i vec2(vec1);
TS_ASSERT_EQUALS(0, vec0.x);
TS_ASSERT_EQUALS(0, vec0.y);
TS_ASSERT_EQUALS(1, vec1.x);
TS_ASSERT_EQUALS(1, vec1.y);
TS_ASSERT_EQUALS(1, vec2.x);
TS_ASSERT_EQUALS(1, vec2.y);
}
void test_vec2f_constructors()
{
Vec2f vec0;
Vec2f vec1(1.0f, 1.0f);
Vec2f vec2(vec1);
TS_ASSERT_EQUALS(0.0f, vec0.x);
TS_ASSERT_EQUALS(0.0f, vec0.y);
TS_ASSERT_EQUALS(1.0f, vec1.x);
TS_ASSERT_EQUALS(1.0f, vec1.y);
TS_ASSERT_EQUALS(1.0f, vec2.x);
TS_ASSERT_EQUALS(1.0f, vec2.y);
}
void test_vector2_get_length()
{
Vec2f vec0(3.0f, 3.0f);
TS_ASSERT_EQUALS(18.0f, vec0.getLengthSquared());
vec0.x = -3.0f;
TS_ASSERT_EQUALS(18.0f, vec0.getLengthSquared());
TS_ASSERT_EQUALS(std::sqrtf(18.0f), vec0.getLength());
Vec2i vec1(4, 2);
TS_ASSERT_EQUALS(20.0f, vec1.getLengthSquared());
TS_ASSERT_EQUALS(std::sqrtf(20.0f), vec1.getLength());
}
void test_vector2_normalization()
{
Vec2f vec0(1.0f, 1.0f);
float targetXY = 1.0f / std::sqrtf(2.0f);
TS_ASSERT_EQUALS(targetXY, vec0.normalized().x);
TS_ASSERT_EQUALS(targetXY, vec0.normalized().y);
vec0.normalize();
TS_ASSERT_EQUALS(targetXY, vec0.x);
TS_ASSERT_EQUALS(targetXY, vec0.y);
float x = 17.53f;
float y = 42.42f;
vec0.x = x;
vec0.y = y;
float targetX = x / std::sqrtf(x * x + y * y);
float targetY = y / std::sqrtf(x * x + y * y);
vec0.normalize();
TS_ASSERT_EQUALS(targetX, vec0.x);
TS_ASSERT_EQUALS(targetY, vec0.y);
}
void test_vector2_comparison()
{
Vec2i vec0(42, 24);
Vec2i vec1(42, 24);
Vec2i vec2(69, 96);
TS_ASSERT_EQUALS(true, vec0.isEqual(vec1));
TS_ASSERT_EQUALS(false, vec0.isEqual(vec2));
TS_ASSERT_EQUALS(true, vec0.isSame(vec0));
TS_ASSERT_EQUALS(false, vec0.isSame(vec1));
Vec2f vec3(42.0f, 24.0f);
Vec2f vec4(42.0f, 24.0f);
Vec2f vec5(69.0f, 96.0f);
TS_ASSERT_EQUALS(true, vec3.isEqual(vec4));
TS_ASSERT_EQUALS(false, vec3.isEqual(vec5));
TS_ASSERT_EQUALS(true, vec3.isSame(vec3));
TS_ASSERT_EQUALS(false, vec3.isSame(vec4));
}
void test_vector2_comparison_operators()
{
Vec2i vec0(42, 24);
Vec2i vec1(42, 24);
Vec2i vec2(69, 96);
TS_ASSERT_EQUALS(true, vec0 == vec0);
TS_ASSERT_EQUALS(true, vec0 == vec1);
TS_ASSERT_EQUALS(false, vec0 == vec2);
TS_ASSERT_EQUALS(false, vec0 != vec0);
TS_ASSERT_EQUALS(false, vec0 != vec1);
TS_ASSERT_EQUALS(true, vec0 != vec2);
Vec2f vec3(42.0f, 24.0f);
Vec2f vec4(42.0f, 24.0f);
Vec2f vec5(69.0f, 96.0f);
TS_ASSERT_EQUALS(true, vec3 == vec3);
TS_ASSERT_EQUALS(true, vec3 == vec4);
TS_ASSERT_EQUALS(false, vec3 == vec5);
TS_ASSERT_EQUALS(false, vec3 != vec3);
TS_ASSERT_EQUALS(false, vec3 != vec4);
TS_ASSERT_EQUALS(true, vec3 != vec5);
}
void test_assignment_operator()
{
Vec2i vec0(42, 24);
Vec2i vec1(69, 96);
vec1 = vec0;
TS_ASSERT_EQUALS(42, vec1.x);
TS_ASSERT_EQUALS(24, vec1.y);
TS_ASSERT_EQUALS(true, vec0.isEqual(vec1));
TS_ASSERT_EQUALS(false, vec0.isSame(vec1));
Vec2i vec2(42.0f, 24.0f);
Vec2i vec3(69.0f, 96.0f);
vec2 = vec3;
TS_ASSERT_EQUALS(69.0f, vec2.x);
TS_ASSERT_EQUALS(96.0f, vec2.y);
TS_ASSERT_EQUALS(true, vec3.isEqual(vec2));
TS_ASSERT_EQUALS(false, vec3.isSame(vec2));
}
void test_addition_operators()
{
Vec2i vec0(-2, 2);
Vec2i vec1(3, -3);
Vec2i vec2 = vec0 + vec1;
TS_ASSERT_EQUALS(1, vec2.x);
TS_ASSERT_EQUALS(-1, vec2.y);
TS_ASSERT_EQUALS(-2, vec0.x);
TS_ASSERT_EQUALS(2, vec0.y);
TS_ASSERT_EQUALS(3, vec1.x);
TS_ASSERT_EQUALS(-3, vec1.y);
vec0 += vec1;
TS_ASSERT_EQUALS(1, vec0.x);
TS_ASSERT_EQUALS(-1, vec0.y);
}
void test_subtraction_operators()
{
Vec2f vec0(-2.0f, 2.0f);
Vec2f vec1(3.0f, -3.0f);
Vec2f vec2 = vec0 - vec1;
TS_ASSERT_EQUALS(-5.0f, vec2.x);
TS_ASSERT_EQUALS(5.0f, vec2.y);
TS_ASSERT_EQUALS(-2.0f, vec0.x);
TS_ASSERT_EQUALS(2.0f, vec0.y);
TS_ASSERT_EQUALS(3.0f, vec1.x);
TS_ASSERT_EQUALS(-3.0f, vec1.y);
vec0 -= vec1;
TS_ASSERT_EQUALS(-5.0f, vec0.x);
TS_ASSERT_EQUALS(5.0f, vec0.y);
}
void test_scalar_multiplication_operators()
{
Vec2f vec0(-2.0f, 2.0f);
Vec2f vec1 = vec0 * 42.0f;
TS_ASSERT_EQUALS(-84.0f, vec1.x);
TS_ASSERT_EQUALS(84.0f, vec1.y);
TS_ASSERT_EQUALS(-2.0f, vec0.x);
TS_ASSERT_EQUALS(2.0f, vec0.y);
vec0 *= 42.0f;
TS_ASSERT_EQUALS(-84.0f, vec0.x);
TS_ASSERT_EQUALS(84.0f, vec0.y);
Vec2i vec2(-2, 2);
Vec2i vec3 = vec2 * 42.5f; //the float is on purpose
TS_ASSERT_EQUALS(-84, vec3.x);
TS_ASSERT_EQUALS(84, vec3.y);
TS_ASSERT_EQUALS(-2, vec2.x);
TS_ASSERT_EQUALS(2, vec2.y);
vec2 *= 42;
TS_ASSERT_EQUALS(-84, vec2.x);
TS_ASSERT_EQUALS(84, vec2.y);
}
void test_dot_product_operator()
{
Vec2f vec0(2.0f, 4.0f);
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);
Vec2f vec3(2, 4);
Vec2f vec4(3, 6);
Vec2f vec5(-2, -1);
TS_ASSERT_EQUALS(30, vec3 * vec4);
TS_ASSERT_EQUALS(-8, vec3 * vec5);
}
void test_scalar_division_operators()
{
Vec2f vec0(42.0f, 24.0f);
Vec2f vec1 = vec0 / 2.0f;
Vec2f vec2 = vec0 / 0.5f;
TS_ASSERT_EQUALS(42.0f, vec0.x);
TS_ASSERT_EQUALS(24.0f, vec0.y);
TS_ASSERT_EQUALS(21.0f, vec1.x);
TS_ASSERT_EQUALS(12.0f, vec1.y);
TS_ASSERT_EQUALS(84.0f, vec2.x);
TS_ASSERT_EQUALS(48.0f, vec2.y);
vec0 /= 2.0f;
TS_ASSERT_EQUALS(21.0f, vec0.x);
TS_ASSERT_EQUALS(12.0f, vec0.y);
Vec2i vec3(42, 24);
Vec2i vec4 = vec3 / 2;
TS_ASSERT_EQUALS(42, vec3.x);
TS_ASSERT_EQUALS(24, vec3.y);
TS_ASSERT_EQUALS(21, vec4.x);
TS_ASSERT_EQUALS(12, vec4.y);
vec3 /= 2;
TS_ASSERT_EQUALS(21, vec3.x);
TS_ASSERT_EQUALS(12, vec3.y);
}
};