From: jpreiss Date: Tue, 2 Jun 2020 01:03:44 +0000 (-0700) Subject: qslerp test, qanglebetween bufix X-Git-Url: https://git.owens.tech/dummy.html/dummy.html/git?a=commitdiff_plain;h=1e7cf10318d4b908be8d69ef6abc7f5255b190c7;p=forks%2Fcmath3d.git qslerp test, qanglebetween bufix --- diff --git a/math3d.h b/math3d.h index 795f302..73375a1 100644 --- a/math3d.h +++ b/math3d.h @@ -713,8 +713,8 @@ static inline float qdot(struct quat a, struct quat b) { static inline float qanglebetween(struct quat a, struct quat b) { float const dot = qdot(qposreal(a), qposreal(b)); // prevent acos domain issues - if (dot > 1.0f - 1e9f) return 0.0f; - if (dot < -1.0f + 1e9f) return M_PI_F; + if (dot > 1.0f - 1e-9f) return 0.0f; + if (dot < -1.0f + 1e-9f) return M_PI_F; return acosf(dot); } static inline bool qeq(struct quat a, struct quat b) { diff --git a/test.c b/test.c index 626587a..9a45d10 100644 --- a/test.c +++ b/test.c @@ -120,7 +120,8 @@ void test_quat_mat_conversions() struct mat33 const m = quat2rotmat(q); struct quat const qq = mat2quat(m); float const angle = qanglebetween(q, qq); - assert(fabs(angle) < radians(1e-4)); + // TODO: seems like a lot of precision loss -- can we improve? + assert(fabs(angle) < radians(0.1f)); } printf("%s passed\n", __func__); } @@ -154,6 +155,36 @@ void test_qvectovec() printf("%s passed\n", __func__); } +void test_qslerp() +{ + srand(0); // deterministic + + int const N = 10000; + + for (int i = 0; i < N; ++i) { + // two random quaternions + struct quat a = randquat(); + struct quat b = randquat(); + + // construct quaternion dq such that b = (dq)^steps * a + int steps = 1 + rand() % 5; + float t = 1.0 / steps; + struct quat q = qslerp(a, b, t); + struct quat dq = qqmul(q, qinv(a)); + + // verify + struct quat b2 = a; + for (int s = 0; s < steps; ++s) { + b2 = qqmul(dq, b2); + } + float angle = qanglebetween(b, b2); + + // TODO: seems like a lot of precision loss -- can we improve? + assert(angle <= radians(0.1f)); + } + printf("%s passed\n", __func__); +} + // micro test framework typedef void (*voidvoid_fn)(void); voidvoid_fn test_fns[] = { @@ -162,6 +193,7 @@ voidvoid_fn test_fns[] = { test_quat_rpy_conversions, test_quat_mat_conversions, test_qvectovec, + test_qslerp, }; static int i_test = -1;