Parcourir la source

test: add several unit tests for rotations with matrices and quaternions.

legacy
Sam Hocevar sam il y a 12 ans
Parent
révision
9e9c18d37e
4 fichiers modifiés avec 175 ajouts et 40 suppressions
  1. +1
    -1
      test/Makefile.am
  2. +49
    -39
      test/unit/quat.cpp
  3. +124
    -0
      test/unit/rotation.cpp
  4. +1
    -0
      win32/testsuite.vcxproj

+ 1
- 1
test/Makefile.am Voir le fichier

@@ -24,7 +24,7 @@ TESTS = testsuite
testsuite_SOURCES = testsuite.cpp \
unit/vector.cpp unit/matrix.cpp unit/half.cpp unit/trig.cpp \
unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp \
unit/array.cpp
unit/array.cpp unit/rotation.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


+ 49
- 39
test/unit/quat.cpp Voir le fichier

@@ -26,11 +26,11 @@ LOLUNIT_FIXTURE(QuaternionTest)

LOLUNIT_TEST(Equality)
{
quat a4(1.0f, 2.0f, 3.0f, 4.0f);
quat b4(0.0f, 2.0f, 3.0f, 4.0f);
quat c4(1.0f, 0.0f, 3.0f, 4.0f);
quat d4(1.0f, 2.0f, 0.0f, 4.0f);
quat e4(1.0f, 2.0f, 3.0f, 0.0f);
quat a4(1.f, 2.f, 3.f, 4.f);
quat b4(0.f, 2.f, 3.f, 4.f);
quat c4(1.f, 0.f, 3.f, 4.f);
quat d4(1.f, 2.f, 0.f, 4.f);
quat e4(1.f, 2.f, 3.f, 0.f);

LOLUNIT_ASSERT_EQUAL(a4, a4);
LOLUNIT_ASSERT_NOT_DIFFERENT(a4, a4);
@@ -47,8 +47,8 @@ LOLUNIT_FIXTURE(QuaternionTest)

LOLUNIT_TEST(UnaryMinus)
{
quat a(1.0f, 3.0f, 2.0f, 4.0f);
quat b(-1.0f, -3.0f, -2.0f, -4.0f);
quat a(1.f, 3.f, 2.f, 4.f);
quat b(-1.f, -3.f, -2.f, -4.f);

LOLUNIT_ASSERT_EQUAL(a, -b);
LOLUNIT_ASSERT_EQUAL(-a, b);
@@ -56,8 +56,8 @@ LOLUNIT_FIXTURE(QuaternionTest)

LOLUNIT_TEST(Conjugate)
{
quat a(1.0f, 3.0f, 2.0f, 4.0f);
quat b(1.0f, -3.0f, -2.0f, -4.0f);
quat a(1.f, 3.f, 2.f, 4.f);
quat b(1.f, -3.f, -2.f, -4.f);

LOLUNIT_ASSERT_EQUAL(a, ~b);
LOLUNIT_ASSERT_EQUAL(~a, b);
@@ -65,31 +65,31 @@ LOLUNIT_FIXTURE(QuaternionTest)

LOLUNIT_TEST(Norm)
{
quat a(2.0f, -2.0f, -8.0f, 3.0f);
quat a(2.f, -2.f, -8.f, 3.f);

LOLUNIT_ASSERT_EQUAL(norm(a), 81.0f);
LOLUNIT_ASSERT_EQUAL(norm(a), 81.f);

quat b = a * ~a;
quat c(norm(a), 0.0f, 0.0f, 0.0f);
quat c(norm(a), 0.f, 0.f, 0.f);

LOLUNIT_ASSERT_EQUAL(b, c);

quat d(2.0f, 3.0f, -4.0f, -1.0f);
quat d(2.f, 3.f, -4.f, -1.f);

LOLUNIT_ASSERT_EQUAL(norm(a * d), norm(a) * norm(d));
}

LOLUNIT_TEST(Base)
{
quat i(0.0f, 1.0f, 0.0f, 0.0f);
quat j(0.0f, 0.0f, 1.0f, 0.0f);
quat k(0.0f, 0.0f, 0.0f, 1.0f);
quat one(1.0f, 0.0f, 0.0f, 0.0f);
quat one(1.f, 0.f, 0.f, 0.f);
quat i(0.f, 1.f, 0.f, 0.f);
quat j(0.f, 0.f, 1.f, 0.f);
quat k(0.f, 0.f, 0.f, 1.f);

LOLUNIT_ASSERT_EQUAL(norm(i), 1.0f);
LOLUNIT_ASSERT_EQUAL(norm(j), 1.0f);
LOLUNIT_ASSERT_EQUAL(norm(k), 1.0f);
LOLUNIT_ASSERT_EQUAL(norm(one), 1.0f);
LOLUNIT_ASSERT_EQUAL(norm(one), 1.f);
LOLUNIT_ASSERT_EQUAL(norm(i), 1.f);
LOLUNIT_ASSERT_EQUAL(norm(j), 1.f);
LOLUNIT_ASSERT_EQUAL(norm(k), 1.f);

LOLUNIT_ASSERT_EQUAL(i * i, -one);
LOLUNIT_ASSERT_EQUAL(j * j, -one);
@@ -106,40 +106,50 @@ LOLUNIT_FIXTURE(QuaternionTest)

LOLUNIT_TEST(Normalize)
{
quat a(2.0f, -2.0f, -8.0f, 3.0f);
quat a(2.f, -2.f, -8.f, 3.f);
quat b = normalize(a);

LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(b), 1.0, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(norm(b), 1.0, 1e-5);
}

LOLUNIT_TEST(Reciprocal)
{
quat a(2.0f, -2.0f, -8.0f, 3.0f);
quat a(2.f, -2.f, -8.f, 3.f);
quat b = re(a);

quat m1 = a * b;
quat m2 = b * a;
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.x, m2.x, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.y, m2.y, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.z, m2.z, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.w, m2.w, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.x, 0.0, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.y, 0.0, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.z, 0.0, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.w, 1.0, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.w, m2.w, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.x, m2.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.y, m2.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.z, m2.z, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.w, 1.0, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.x, 0.0, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.y, 0.0, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m1.z, 0.0, 1e-5);
}

LOLUNIT_TEST(Rotation)
{
quat a = quat::rotate(10.0f, vec3(1, 0, 0));
quat b = quat::rotate(20.0f, vec3(1, 0, 0));
/* Check that rotating 10 degrees twice means rotating 20 degrees */
quat a = quat::rotate(10.f, vec3(1, 0, 0));
quat b = quat::rotate(20.f, vec3(1, 0, 0));
quat c = a * a;

LOLUNIT_ASSERT_DOUBLES_EQUAL(a.w, a.w, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(a.x, a.x, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(a.y, a.y, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(a.z, a.z, 1e-8);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.w, b.w, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.x, b.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.y, b.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.z, b.z, 1e-5);

/* Check that rotating 10 degrees then 20 is the same as 20 then 10 */
quat d = a * b;
quat e = b * a;

LOLUNIT_ASSERT_DOUBLES_EQUAL(e.w, d.w, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(e.x, d.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(e.y, d.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(e.z, d.z, 1e-5);
}
};



+ 124
- 0
test/unit/rotation.cpp Voir le fichier

@@ -0,0 +1,124 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2012 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(RotationTest)
{
void SetUp() {}

void TearDown() {}

LOLUNIT_TEST(Rotate2D)
{
/* Check that rotation is CCW */
mat2 m90 = mat2::rotate(90.f);

vec2 a(2.f, 3.f);
vec2 b = m90 * a;

LOLUNIT_ASSERT_DOUBLES_EQUAL(b.x, -a.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(b.y, a.x, 1e-5);
}

LOLUNIT_TEST(Compose2D)
{
/* Check that rotating 20 degrees twice means rotating 40 degrees */
mat2 m20 = mat2::rotate(20.f);
mat2 m40 = mat2::rotate(40.f);
mat2 m20x20 = m20 * m20;

LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][0], m40[0][0], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][0], m40[1][0], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][1], m40[0][1], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][1], m40[1][1], 1e-5);
}

LOLUNIT_TEST(Rotate3D)
{
/* Check that rotation is CCW around each axis */
mat3 m90x = mat3::rotate(90.f, 1.f, 0.f, 0.f);
mat3 m90y = mat3::rotate(90.f, 0.f, 1.f, 0.f);
mat3 m90z = mat3::rotate(90.f, 0.f, 0.f, 1.f);

vec3 a(2.f, 3.f, 4.f);
vec3 b = m90x * a;
vec3 c = m90y * a;
vec3 d = m90z * a;

LOLUNIT_ASSERT_DOUBLES_EQUAL(b.x, a.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(b.y, -a.z, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(b.z, a.y, 1e-5);

LOLUNIT_ASSERT_DOUBLES_EQUAL(c.x, a.z, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.y, a.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.z, -a.x, 1e-5);

LOLUNIT_ASSERT_DOUBLES_EQUAL(d.x, -a.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(d.y, a.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(d.z, a.z, 1e-5);
}

LOLUNIT_TEST(Compose3D)
{
/* Check that rotating 20 degrees twice means rotating 40 degrees */
mat3 m20 = mat3::rotate(20.f, 1.f, 2.f, 3.f);
mat3 m40 = mat3::rotate(40.f, 1.f, 2.f, 3.f);
mat3 m20x20 = m20 * m20;

LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][0], m40[0][0], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][0], m40[1][0], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[2][0], m40[2][0], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][1], m40[0][1], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][1], m40[1][1], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[2][1], m40[2][1], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[0][2], m40[0][2], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[1][2], m40[1][2], 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(m20x20[2][2], m40[2][2], 1e-5);
}

LOLUNIT_TEST(QuaternionTransform)
{
/* Check that rotating using a quaternion is the same as rotating
* using a matrix */
mat3 m20 = mat3::rotate(20.f, 1.f, 2.f, 3.f);
quat q20 = quat::rotate(20.f, 1.f, 2.f, 3.f);
vec3 a(-2.f, 4.f, 3.f);

vec3 b = m20 * a;
vec3 c = q20.transform(a);

LOLUNIT_ASSERT_DOUBLES_EQUAL(c.x, b.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.y, b.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(c.z, b.z, 1e-5);
}

LOLUNIT_TEST(QuaternionFromMatrix)
{
quat q1 = quat::rotate(20.f, 1.f, 2.f, 3.f);
quat q2 = quat(mat3::rotate(20.f, 1.f, 2.f, 3.f));

LOLUNIT_ASSERT_DOUBLES_EQUAL(q2.w, q1.w, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(q2.x, q1.x, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(q2.y, q1.y, 1e-5);
LOLUNIT_ASSERT_DOUBLES_EQUAL(q2.z, q1.z, 1e-5);
}
};

} /* namespace lol */


+ 1
- 0
win32/testsuite.vcxproj Voir le fichier

@@ -36,6 +36,7 @@
<ClCompile Include="..\test\unit\matrix.cpp" />
<ClCompile Include="..\test\unit\quat.cpp" />
<ClCompile Include="..\test\unit\real.cpp" />
<ClCompile Include="..\test\unit\rotation.cpp" />
<ClCompile Include="..\test\unit\trig.cpp" />
<ClCompile Include="..\test\unit\vector.cpp" />
</ItemGroup>


Chargement…
Annuler
Enregistrer