Do spherical linear interpolation when we animate onto a workplane.

[git-p4: depot-paths = "//depot/solvespace/": change = 1722]
This commit is contained in:
Jonathan Westhues 2008-05-14 06:23:58 -08:00
parent 21c0c87d8e
commit e8fbf81de5
3 changed files with 26 additions and 1 deletions

2
dsc.h
View File

@ -30,6 +30,8 @@ public:
Vector RotationN(void);
Vector Rotate(Vector p);
Quaternion ToThe(double p);
Quaternion Inverse(void);
Quaternion Times(Quaternion b);
};

View File

@ -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();

View File

@ -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 };