2 * Ken Shoemake's Quaternion rotation controller
11 static Point ctlcen; /* center of qball */
12 static int ctlrad; /* radius of qball */
13 static Quaternion *axis; /* constraint plane orientation, 0 if none */
15 * Convert a mouse point into a unit quaternion, flattening if
16 * constrained to a particular plane.
18 static Quaternion mouseq(Point p){
19 double qx=(double)(p.x-ctlcen.x)/ctlrad;
20 double qy=(double)(p.y-ctlcen.y)/ctlrad;
21 double rsq=qx*qx+qy*qy;
38 l=q.i*axis->i+q.j*axis->j+q.k*axis->k;
42 l=sqrt(q.i*q.i+q.j*q.j+q.k*q.k);
51 void qball(Rectangle r, Mouse *m, Quaternion *result, void (*redraw)(void), Quaternion *ap){
55 ctlcen=divpt(addpt(r.min, r.max), 2);
56 rad=divpt(subpt(r.max, r.min), 2);
57 ctlrad=(rad.x<rad.y?rad.x:rad.y)-BORDER;
58 down=qinv(mouseq(m->xy));
62 if(!m->buttons) break;
63 *result=qmul(q, qmul(down, mouseq(m->xy)));