URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-25 Simon Nivault <simon.nivault(a)lrde.epita.fr>
Add interpolation features for quaternions.
* mln/value/quat.hh: Update.
---
quat.hh | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 84 insertions(+), 1 deletion(-)
Index: trunk/milena/mln/value/quat.hh
===================================================================
--- trunk/milena/mln/value/quat.hh (revision 1167)
+++ trunk/milena/mln/value/quat.hh (revision 1168)
@@ -112,8 +112,25 @@
bool about_equal(const T& f, const T& q);
bool about_equal(const quat& p, const quat& q);
+ // Misc.
- // meths and procs bodies...
+ bool interpol_ok(const quat& p, const quat& q, float h);
+
+ // Linear Quaternion Interpolation.
+
+ quat lerp(const quat& p, const quat& q, float h);
+
+ // Spherical Linear Quaternion Interpolation.
+
+ quat slerp(const quat& p, const quat& q, float h);
+
+ quat slerp_2(const quat& p, const quat& q, float h);
+
+ quat slerp_3(const quat& p, const quat& q, float h);
+
+ quat slerp_4(const quat& p, const quat& q, float h);
+
+ quat slerp_5(const quat& p, const quat& q, float h);
# ifndef MLN_INCLUDE_ONLY
@@ -337,6 +354,72 @@
return about_equal<float>(norm::l2(p - q), 0);
}
+ // Misc.
+
+ bool interpol_ok(const quat& p, const quat& q, float h)
+ {
+ return
+ p.is_unit() &&
+ q.is_unit() &&
+ h >= 0 &&
+ h <= 1;
+ }
+
+
+ // Linear Quaternion Interpolation.
+
+ quat lerp(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ return (1 - h) * p + h * q;
+ }
+
+
+ // Spherical Linear Quaternion Interpolation.
+
+ quat slerp(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ float omega = acos(p.sprod(q));
+ return
+ about_equal(omega, 0.f) ?
+ lerp(p, q, h) :
+ quat((sin((1-h)*omega) * p + sin(h*omega) * q) / sin(omega));
+ }
+
+ quat slerp_2(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ quat tmp = p * pow(p.conj() * q, h);
+ assert(about_equal(tmp, slerp(p, q, h)));
+ return tmp;
+ }
+
+ quat slerp_3(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ quat tmp = pow(p * q.conj(), 1 - h) * q;
+ assert(about_equal(tmp, slerp(p, q, h)));
+ return tmp;
+ }
+
+ quat slerp_4(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ quat tmp = pow(q * p.conj(), h) * p;
+ assert(about_equal(tmp, slerp(p, q, h)));
+ return tmp;
+ }
+
+ quat slerp_5(const quat& p, const quat& q, float h)
+ {
+ assert(interpol_ok(p, q, h));
+ quat tmp = q * pow(q.conj() * p, 1 - h);
+ assert(about_equal(tmp, slerp(p, q, h)));
+ return tmp;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::value