| @@ -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 */ | |||