diff --git a/dsc.h b/dsc.h index df30bbe..2acb1aa 100644 --- a/dsc.h +++ b/dsc.h @@ -30,6 +30,8 @@ public: Vector RotationN(void); Vector Rotate(Vector p); + Quaternion ToThe(double p); + Quaternion Inverse(void); Quaternion Times(Quaternion b); }; diff --git a/graphicswin.cpp b/graphicswin.cpp index 68bb665..31029e4 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -158,9 +158,10 @@ void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) { (SDWORD)(100 + 1000*mp + 0.4*mo); SDWORD tn, t0 = GetMilliseconds(); double s = 0; + Quaternion dq = quatf.Times(quat0.Inverse()); do { offset = (offset0.ScaledBy(1 - s)).Plus(offsetf.ScaledBy(s)); - Quaternion quat = (quat0.ScaledBy(1 - s)).Plus(quatf.ScaledBy(s)); + Quaternion quat = (dq.ToThe(s)).Times(quat0); quat = quat.WithMagnitude(1); projRight = quat.RotationU(); diff --git a/util.cpp b/util.cpp index 7b532f6..0a9fb8c 100644 --- a/util.cpp +++ b/util.cpp @@ -132,6 +132,28 @@ Vector Quaternion::Rotate(Vector p) { RotationN().ScaledBy(p.z)); } +Quaternion Quaternion::Inverse(void) { + Quaternion r; + r.w = w; + r.vx = -vx; + r.vy = -vy; + r.vz = -vz; + return r.WithMagnitude(1); // not that the normalize should be reqd +} + +Quaternion Quaternion::ToThe(double p) { + Quaternion r; + Vector axis = Vector::MakeFrom(vx, vy, vz); + double theta = acos(w); // okay, since magnitude is 1, so -1 <= w <= 1 + theta *= p; + r.w = cos(theta); + axis = axis.WithMagnitude(sin(theta)); + r.vx = axis.x; + r.vy = axis.y; + r.vz = axis.z; + return r; +} + Quaternion Quaternion::Times(Quaternion b) { double sa = w, sb = b.w; Vector va = { vx, vy, vz };