Utility: Vector2
2d template vector (with typedefs for int and float) review id = 5
This commit is contained in:
@@ -67,6 +67,8 @@ add_files(
|
||||
utility/logging/LogManager.h
|
||||
utility/logging/LogMessage.h
|
||||
|
||||
utility/math/Vector2.h
|
||||
|
||||
utility/ConfigManager.cpp
|
||||
utility/ConfigManager.h
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -4,4 +4,5 @@ add_files(
|
||||
ConfigManagerTestSuite.h
|
||||
LogManagerTestSuite.h
|
||||
UtilityTestSuite.h
|
||||
Vector2TestSuite.h
|
||||
)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user