@@ -107,6 +107,11 @@ template<> void ivec2::printf() const | |||
Log::Debug("[ %i %i ]\n", x, y); | |||
} | |||
template<> void cmplx::printf() const | |||
{ | |||
Log::Debug("[ %6.6f %6.6f ]\n", x, y); | |||
} | |||
template<> void vec3::printf() const | |||
{ | |||
Log::Debug("[ %6.6f %6.6f %6.6f ]\n", x, y, z); | |||
@@ -152,6 +157,11 @@ template<> std::ostream &operator<<(std::ostream &stream, ivec2 const &v) | |||
return stream << "(" << v.x << ", " << v.y << ")"; | |||
} | |||
template<> std::ostream &operator<<(std::ostream &stream, icmplx const &v) | |||
{ | |||
return stream << "(" << v.x << ", " << v.y << ")"; | |||
} | |||
template<> std::ostream &operator<<(std::ostream &stream, ivec3 const &v) | |||
{ | |||
return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")"; | |||
@@ -174,6 +184,11 @@ template<> std::ostream &operator<<(std::ostream &stream, vec2 const &v) | |||
return stream << "(" << v.x << ", " << v.y << ")"; | |||
} | |||
template<> std::ostream &operator<<(std::ostream &stream, cmplx const &v) | |||
{ | |||
return stream << "(" << v.x << ", " << v.y << ")"; | |||
} | |||
template<> std::ostream &operator<<(std::ostream &stream, vec3 const &v) | |||
{ | |||
return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")"; | |||
@@ -38,6 +38,7 @@ namespace lol | |||
typedef tname<uint64_t> u64##suffix; | |||
VECTOR_TYPES(Vec2, vec2) | |||
VECTOR_TYPES(Cmplx, cmplx) | |||
VECTOR_TYPES(Vec3, vec3) | |||
VECTOR_TYPES(Vec4, vec4) | |||
VECTOR_TYPES(Quat, quat) | |||
@@ -117,6 +118,24 @@ VECTOR_TYPES(Mat4, mat4) | |||
\ | |||
void printf() const; | |||
#define COMPLEX_OPS() \ | |||
inline type_t operator *(type_t const &val) const \ | |||
{ \ | |||
return type_t(x * val.x - y * val.y, x * val.y + y * val.x); \ | |||
} \ | |||
\ | |||
inline type_t operator *=(type_t const &val) \ | |||
{ \ | |||
return *this = (*this) * val; \ | |||
} \ | |||
\ | |||
inline type_t operator ~() const \ | |||
{ \ | |||
return type_t(x, -y); \ | |||
} \ | |||
\ | |||
inline T norm() const { return len(); } | |||
#define QUATERNION_OPS() \ | |||
inline type_t operator *(type_t const &val) const \ | |||
{ \ | |||
@@ -257,6 +276,47 @@ template <typename T> struct Vec2 | |||
union { T y; T b; T j; }; | |||
}; | |||
/* | |||
* 2-element complexes | |||
*/ | |||
template <typename T> struct Cmplx | |||
{ | |||
typedef Cmplx<T> type_t; | |||
inline Cmplx() { } | |||
inline Cmplx(T val) : x(val), y(0) { } | |||
inline Cmplx(T _x, T _y) : x(_x), y(_y) { } | |||
LINEAR_OPS() | |||
COMPLEX_OPS() | |||
#if !defined __ANDROID__ | |||
template<typename U> | |||
friend std::ostream &operator<<(std::ostream &stream, Cmplx<U> const &v); | |||
#endif | |||
T x, y; | |||
}; | |||
template<typename T> | |||
static inline Cmplx<T> re(Cmplx<T> const &val) | |||
{ | |||
return ~val / val.sqlen(); | |||
} | |||
template<typename T> | |||
static inline Cmplx<T> operator /(T x, Cmplx<T> const &y) | |||
{ | |||
return x * re(y); | |||
} | |||
template<typename T> | |||
static inline Cmplx<T> operator /(Cmplx<T> x, Cmplx<T> const &y) | |||
{ | |||
return x * re(y); | |||
} | |||
/* | |||
* 3-element vectors | |||
*/ | |||
@@ -399,6 +459,7 @@ static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y) | |||
} | |||
GLOBALS(Vec2) | |||
GLOBALS(Cmplx) | |||
GLOBALS(Vec3) | |||
GLOBALS(Vec4) | |||
GLOBALS(Quat) | |||
@@ -24,7 +24,7 @@ TESTS = testsuite | |||
testsuite_SOURCES = testsuite.cpp \ | |||
unit/matrix.cpp unit/half.cpp unit/trig.cpp unit/build.cpp \ | |||
unit/real.cpp unit/image.cpp unit/quat.cpp | |||
unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp | |||
testsuite_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ | |||
testsuite_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ | |||
testsuite_DEPENDENCIES = $(top_builddir)/src/liblol.a | |||
@@ -0,0 +1,110 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#include "core.h" | |||
#include "lol/unit.h" | |||
namespace lol | |||
{ | |||
LOLUNIT_FIXTURE(ComplexTest) | |||
{ | |||
void SetUp() {} | |||
void TearDown() {} | |||
LOLUNIT_TEST(Equality) | |||
{ | |||
cmplx a2(1.0f, 2.0f); | |||
cmplx b2(0.0f, 2.0f); | |||
cmplx c2(1.0f, 0.0f); | |||
LOLUNIT_ASSERT_EQUAL(a2, a2); | |||
LOLUNIT_ASSERT_NOT_DIFFERENT(a2, a2); | |||
LOLUNIT_ASSERT_DIFFERENT(a2, b2); | |||
LOLUNIT_ASSERT_NOT_EQUAL(a2, b2); | |||
LOLUNIT_ASSERT_DIFFERENT(a2, c2); | |||
LOLUNIT_ASSERT_NOT_EQUAL(a2, c2); | |||
} | |||
LOLUNIT_TEST(UnaryMinus) | |||
{ | |||
cmplx a(1.0f, 3.0f); | |||
cmplx b(-1.0f, -3.0f); | |||
LOLUNIT_ASSERT_EQUAL(a, -b); | |||
LOLUNIT_ASSERT_EQUAL(-a, b); | |||
} | |||
LOLUNIT_TEST(Conjugate) | |||
{ | |||
cmplx a(1.0f, 3.0f); | |||
cmplx b(1.0f, -3.0f); | |||
LOLUNIT_ASSERT_EQUAL(a, ~b); | |||
LOLUNIT_ASSERT_EQUAL(~a, b); | |||
} | |||
LOLUNIT_TEST(Norm) | |||
{ | |||
cmplx a(3.0f, -4.0f); | |||
LOLUNIT_ASSERT_EQUAL(a.norm(), 5.0f); | |||
cmplx b = a * ~a; | |||
cmplx c = a.norm() * a.norm(); | |||
LOLUNIT_ASSERT_EQUAL(b, c); | |||
cmplx d(5.0f, 12.0f); | |||
LOLUNIT_ASSERT_EQUAL(d.norm(), 13.0f); | |||
LOLUNIT_ASSERT_EQUAL((a * d).norm(), a.norm() * d.norm()); | |||
} | |||
LOLUNIT_TEST(Base) | |||
{ | |||
cmplx one(1.0f, 0.0f); | |||
cmplx i(0.0f, 1.0f); | |||
LOLUNIT_ASSERT_EQUAL(one.norm(), 1.0f); | |||
LOLUNIT_ASSERT_EQUAL(i.norm(), 1.0f); | |||
LOLUNIT_ASSERT_EQUAL(i * i, -one); | |||
} | |||
LOLUNIT_TEST(Normalize) | |||
{ | |||
cmplx a(3.0f, -4.0f); | |||
cmplx b = normalize(a); | |||
LOLUNIT_ASSERT_DOUBLES_EQUAL(b.norm(), 1.0, 1e-8); | |||
} | |||
LOLUNIT_TEST(Reciprocal) | |||
{ | |||
cmplx a(3.0f, -4.0f); | |||
cmplx b = re(a); | |||
LOLUNIT_ASSERT_EQUAL(a * b, b * a); | |||
cmplx c = 1.0f; | |||
LOLUNIT_ASSERT_EQUAL(a * b, c); | |||
} | |||
}; | |||
} /* namespace lol */ | |||