Download - Quaternion and Virtual Trackball
![Page 1: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/1.jpg)
Quaternion and Virtual Trackball
CSE 781 Introduction to 3D Image Generation
Han-Wei ShenWinter 2007
![Page 2: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/2.jpg)
Euler Rotation Problems Gimbal Lock – lose one degree of freedom Problem happens when the axes of rotation
line up on top of each other. For example:
x
y
z
Step one: Rotate(0, 0,0,1) Step2: Rotate(90, 0,1,0) Step 3: Rotate(??, 0,0,1) This is same as rotation x !!
xy
z
xy
z
![Page 3: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/3.jpg)
Euler Rotation Problems Rotations with Euler angles to change from one
orientation to another are not unique. Example: (x,y,z) rotation to achieve the following:
z
x
yR
R
Rotate(180, 1,0,0) Rotate(180, 0,1,0) then Rotate(180,0,0,1)Euler angles: (0,0,0) -> (180,0,0) Euler angles: (0,0,0) -> (0,180,180)
x
y
OR
R
x
yx
y
R
z
yz
z
z
![Page 4: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/4.jpg)
Quaternion Invented in 1843 as an extension to the
complex numbers Used by computer graphics since 1985 Quaternion:
Provide an alternative method to specify rotation Can avoid the gimbal lock problem Allow unique, smooth and continuous rotation
interpolations
![Page 5: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/5.jpg)
Mathematical Background A quaternion is a 4-tuple of real number, which can
be seen as a vector and a scalar Q = [qx, qy, qz, qw] = qv + qw, where qw is the real part and
qv = iqx + jqy + kqz = (qx, qy, qz) is the imaginary part i*i = j*j = k*k = -1; j*k= -k*j= i; k*i=-i*k=j; i*j=-j*i= k; All the regular vector operations (dot product, cross
product, scalar product, addition, etc) applied to the imaginary part qv
![Page 6: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/6.jpg)
Basic Operations Multiplication: QR = (qv x rv + rwqv + qwrv, qwrw - qv.rv) Addition: Q+R = (qv+rv, qw+rw) Conjugate: Q* = (-qv, qw) Norm (magnitude) = QQ* = Q*Q =
qx*qx+qy*qy+qz*qz+qw*qw
Identity i = (0,1) Inverse Q = (1/ Norm(Q)) Q* Some more rules can be found in the reference
book (real time rendering) pp46
real
Imaginary
-1
![Page 7: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/7.jpg)
Polar Representation Remember a 2D unit complex number cos + i sin = e A unit quaternion Q may be written as: Q = (sin uq , cos) = cos + sin uqwhere
uq is a unit 3-tuple vector We can also write this unit quaternion as: Q = e
i
uq
![Page 8: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/8.jpg)
Quaternion Rotation A rotation can be represented by a unit
quaternion Q = (sinuq, cos) Given a point p = (x,y,z) -> we first convert it to a
quaternion p’ = ix+jy+kz+ 0 = (pv, 0) Then, Qp’Q is in fact a rotation of p around uq by
an angle 2 !!
-1
![Page 9: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/9.jpg)
Rotation Concatenation Concatenation is easy – just multiply all the
quaternions Q1, Q2, Q3, …. Together
There is a one-to-one mapping between a quaternion rotation and 4x4 rotation matrix.
(Q3 (Q2 ( Q1 P’ Q1 ) Q2 ) Q3 ) =
(Q3*Q2*Q1) P’ (Q1*Q2*Q3 )
-1 -1 -1
-1 -1 -1
![Page 10: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/10.jpg)
Quaternion to Rotation Matrix Given a quaternion w + xi +yj + kz, it can be
translated to the rotation matrix R: 1-2y^2-2z^2 2xy+2wz 2xz-2wy R = 2xy-2wz 1-2x^2-2z^2 2yz+2wx 2xz+2wy 2yz-2wx 1-2x^2-2y^2
Also you can convert a matrix to quaternion (see the reference book for detail)
![Page 11: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/11.jpg)
Interpolation of Rotation Should avoid sudden change of orientation
and also should maintain a constant angular speed
Each rotation can be represented as a point on the surface of a 4D unit sphere Need to perform smooth interpolation along this
4D sphere
A BRHow to interpolate
A and B to get R?
![Page 12: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/12.jpg)
Interpolation Rotation Spherical Linear Interpolation (slerp): Given two unit quaternion (i.e., two rotations), we
can create a smooth interpolation using slerp: slerp(Q1, Q2, t) = sin ((1-t)) sin(t) sin sin where 0<=t<=1 To compute we can use this property: cos = Q1xQ2x+Q1yQ2y+Q1zQ2z+Q1wQ2w
Q1+ Q2
![Page 13: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/13.jpg)
3D Rotations with Euler Angles A simple but non-intuitive method – specify
separate x, y, z axis rotation angles based on the mouse’s horizontal, vertical, and diagonal movements
cos() -sin() 0 0 sin() cos() 0 0 0 0 1 0 0 0 0 1
cos() 0 sin() 0 0 1 0 0 -sin() 0 cos() 0 0 0 0 1
1 0 0 0 0 cos() -sin() 0 0 sin() cos() 0 0 0 0 1
OpenGL - glRotatef(, 0,0,1) glRotatef(, 0,1,0) glRotatef(, 1,0,0)
![Page 14: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/14.jpg)
Euler Rotation Problems Gimbal Lock – lose one degree of freedom Problem happens when the axes of rotation
line up on top of each other. For example:
z
Step one: Rotate(0, 1,0,0) Step2: Rotate(90, 0,1,0) Step 3: Rotate(??, 0,0,1) This is same as rotation x !!
y y
x
y x
z
x
z
![Page 15: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/15.jpg)
3D Rotations with Trackball Imagine the objects are
rotated along with a imaginary hemi-sphere
![Page 16: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/16.jpg)
Virtual Trackball
Allow the user to define 3D rotation using mouse click in 2D windows
Work similarly like the hardware trackball devices
![Page 17: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/17.jpg)
Virtual Trackball Superimpose a hemi-
sphere onto the viewport
This hemi-sphere is projected to a circle inscribed to the viewport
The mouse position is projected orthographically to this hemi-sphere
z
y
(x,y,0)
x
![Page 18: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/18.jpg)
Virtual Trackball Keep track the previous mouse
position and the current position Calculate their projection positions
p1 and p2 to the virtual hemi-sphere We then rotate the sphere from p1
to p2 by finding the proper rotation axis and angle
This rotation ( in eye space!) is then applied to the object (call the rotation before you define the camera with gluLookAt())
You should also remember to accumulate the current rotation to the previous modelview matrix
x
y
z
![Page 19: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/19.jpg)
Virtual Trackball The axis of rotation is given by the normal to
the plane determined by the origin, p1 , and p2
The angle between p1
and p2 is given by
x
y
zn = p1 p1
| sin | = ||||
||
21 ppn
![Page 20: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/20.jpg)
Virtual Trackball How to calculate p1 and p2? Assuming the mouse position is (x,y), then the sphere point P
also has x and y coordinates equal to x and y Assume the radius of the hemi-sphere is 1. So the z
coordinate of P is
Note: normalize viewport y extend to -1 to 1 If a point is outside the circle, project it to the nearest point on the circle (set z to 0 and renormalize (x,y))
22 yx1
z
y
(x,y,0)
x
![Page 21: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/21.jpg)
Virtual Trackball
Visualization of the algorithm
![Page 22: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/22.jpg)
Example Example from Ed Angel’s OpenGL Primer In this example, the virtual trackball is used to
rotate a color cube The code for the colorcube function is omitted I will not cover the following code, but I am
sure you will find it useful
![Page 23: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/23.jpg)
Initialization#define bool int /* if system does not support bool type */#define false 0#define true 1#define M_PI 3.14159 /* if not in math.h */
int winWidth, winHeight;
float angle = 0.0, axis[3], trans[3];
bool trackingMouse = false;bool redrawContinue = false;bool trackballMove = false;
float lastPos[3] = {0.0, 0.0, 0.0};int curx, cury;int startX, startY;
![Page 24: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/24.jpg)
The Projection Stepvoidtrackball_ptov(int x, int y, int width, int height, float v[3]){ float d, a; /* project x,y onto a hemisphere centered within width, height ,
note z is up here*/ v[0] = (2.0*x - width) / width; v[1] = (height - 2.0F*y) / height; d = sqrt(v[0]*v[0] + v[1]*v[1]); v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0)); a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] *= a; v[1] *= a; v[2] *= a;}
![Page 25: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/25.jpg)
glutMotionFunc (1)Void mouseMotion(int x, int y){ float curPos[3], dx, dy, dz; /* compute position on hemisphere */ trackball_ptov(x, y, winWidth, winHeight, curPos); if(trackingMouse) { /* compute the change in position on the hemisphere */ dx = curPos[0] - lastPos[0]; dy = curPos[1] - lastPos[1]; dz = curPos[2] - lastPos[2];
![Page 26: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/26.jpg)
glutMotionFunc (2)if (dx || dy || dz) { /* compute theta and cross product */ angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz); axis[0] = lastPos[1]*curPos[2] – lastPos[2]*curPos[1]; axis[1] = lastPos[2]*curPos[0] – lastPos[0]*curPos[2]; axis[2] = lastPos[0]*curPos[1] – lastPos[1]*curPos[0]; /* update position */ lastPos[0] = curPos[0]; lastPos[1] = curPos[1]; lastPos[2] = curPos[2]; } } glutPostRedisplay();}
![Page 27: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/27.jpg)
Idle and Display Callbacksvoid spinCube(){ if (redrawContinue) glutPostRedisplay();}
void display(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if (trackballMove) { glRotatef(angle, axis[0], axis[1], axis[2]);
}colorcube();
glutSwapBuffers();}
![Page 28: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/28.jpg)
Mouse Callbackvoid mouseButton(int button, int state, int x, int y){if(button==GLUT_RIGHT_BUTTON) exit(0);
/* holding down left button allows user to rotate cube */if(button==GLUT_LEFT_BUTTON) switch(state)
{ case GLUT_DOWN: y=winHeight-y; startMotion( x,y); break;
case GLUT_UP: stopMotion( x,y); break;
} }
![Page 29: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/29.jpg)
Start Functionvoid startMotion(int x, int y){ trackingMouse = true; redrawContinue = false; startX = x; startY = y; curx = x; cury = y; trackball_ptov(x, y, winWidth, winHeight, lastPos); trackballMove=true;}
![Page 30: Quaternion and Virtual Trackball](https://reader034.vdocument.in/reader034/viewer/2022042519/56815a93550346895dc80c46/html5/thumbnails/30.jpg)
Stop Functionvoid stopMotion(int x, int y){ trackingMouse = false; /* check if position has changed */ if (startX != x || startY != y) redrawContinue = true;
else { angle = 0.0; redrawContinue = false; trackballMove = false;
}}