libcruft-util/test/affine.cpp

120 lines
3.3 KiB
C++

#include "tap.hpp"
#include "vector.hpp"
#include "matrix.hpp"
#include "quaternion.hpp"
#include "coord/iostream.hpp"
///////////////////////////////////////////////////////////////////////////////
void
test_matrix_identities (util::TAP::logger &tap)
{
static constexpr util::vector3f UP {0,1,0};
{
util::point3f p { 1, 2, 3 };
auto m = util::matrix4f::translation (0-p);
auto x = m * p.homog<4> ();
tap.expect_eq (x, util::point4f {0,0,0,1}, "trivial translation to origin");
}
{
util::point3f p {0};
auto m = util::matrix4f::rotation (1, { 1, 0, 0 }) *
util::matrix4f::rotation (1, { 0, 1, 0 }) *
util::matrix4f::rotation (1, { 0, 0, 1 });
auto x = m * p.homog<4> ();
tap.expect_eq (x, util::point4f {0,0,0,1}, "trivial rotation at origin");
}
{
util::point3f eye { 1, 2, 3 };
util::point3f tgt { 0, 0, 0 };
auto m = util::matrix4f::look_at (eye, tgt, UP);
auto x = m * eye.homog<4> ();
tap.expect_eq (x, util::point4f {0,0,0,1}, "look_at eye translation");
}
{
util::point3f eye { 1, 2, 3 };
util::point3f tgt { 4, 5, 6 };
auto m = util::matrix4f::look_at (eye, tgt, UP);
auto x = m * eye.homog<4> ();
tap.expect_eq (x, util::point4f {0,0,0,1}, "look_at eye translation with target");
}
}
///////////////////////////////////////////////////////////////////////////////
void
test_mq_axis (util::TAP::logger &tap)
{
static const struct {
util::vector3f euler;
const char *msg;
} TESTS[] = {
{ { 1, 0, 0 }, "x-axis" },
{ { 0, 1, 0 }, "y-axis" },
{ { 0, 0, 1 }, "z-axis" },
};
for (auto t: TESTS) {
auto m = util::matrix4f::rotation (1, t.euler);
auto q = util::quaternionf::angle_axis (1, t.euler);
auto diff = sum (abs (m - q.as_matrix ()));
tap.expect_le (diff, 1e-6f, "matrix/quaternion rotation identities, %s", t.msg);
}
}
///////////////////////////////////////////////////////////////////////////////
void
test_mq_euler (util::TAP::logger &tap)
{
static const struct {
util::vector3f euler;
const char *msg;
} TESTS[] = {
{ { 0, 0, 0 }, "zeroes" },
{ { 1, 0, 0 }, "x-axis" },
{ { 0, 1, 0 }, "y-axis" },
{ { 0, 0, 1 }, "z-axis" },
{ { 1, 1, 1 }, "ones" },
{ { 9, 9, 9 }, "nines" }
};
for (auto t: TESTS) {
auto m = util::matrix4f::rotation (t.euler[0], { 1, 0, 0 }) *
util::matrix4f::rotation (t.euler[1], { 0, 1, 0 }) *
util::matrix4f::rotation (t.euler[2], { 0, 0, 1 });
auto q = (
util::quaternionf::angle_axis (t.euler[0], { 1, 0, 0 }) *
util::quaternionf::angle_axis (t.euler[1], { 0, 1, 0 }) *
util::quaternionf::angle_axis (t.euler[2], { 0, 0, 1 })
).as_matrix ();
auto diff = util::sum (abs (m - q));
tap.expect_le (diff, 1e-6f, "matrix-quaternion xyz euler rotations, %s", t.msg);
}
}
///////////////////////////////////////////////////////////////////////////////
int
main (int, char**)
{
util::TAP::logger tap;
test_matrix_identities (tap);
test_mq_axis (tap);
test_mq_euler (tap);
return tap.status ();
}