TrackBall Class (with no Gimbal Lock)
To download:
1 | bzr branch http://bazaar.enseed.com/lib/Generic/ look under Geometry/TrackBall.h |
A trackball is useful when you display 3D objects and want to let the user change the position of the camera around an object by click-and-dragging the mouse. A trackball simulates a 3D ball in the scene, and rotates as though the user was dragging a point on the surface of sphere.
Here is how to trackball computes the rotation:
- find the line between the click point and the current point
- find the position of these points on the virtual sphere
- find the axis of rotation (it is perpendicular to the two points’ line)
- estimate the angle of rotation based on the distance of the two points on the sphere
- represend that rotation using a quaternion. This quaternion can then be used to extract a rotation matrix.
It’s quite trivial to use. Say you have a 640×480 window. You would create a TrackBall with radius 240 and a center at (320, 240):
1 2 | // create the trackball TrackBall trackball(240, Point2f(320.0f, 240.0f)); |
When you get a “mouse down” event, you’d tell the trackball to begin tracking:
1 2 3 4 5 | // we had a mouse down void MouseDown(Point2f mousePos) { trackball.beginTracking(mousePos); } |
Finally, when the mouse is dragged, you update the trackball and extract the rotation
1 2 3 4 5 6 7 8 9 | // we had a mouse drag event void MouseDrag(Point2f mousePos) { Quatf q = trackball.track(mousePos); Matrix4x4 rotMatrix; q.to4x4Matrix(&rotMatrix); // rotMatrix now holds a rotation matrix for our view or object } |
If you are doing OpenGL, you can use this matrix to change your view:
1 2 3 4 5 6 7 8 9 | glMatrixMode(GL_PROJECTION); glLoadIdentity(); // setup your view here // ... // multiply with our rotation matrix. We have // to transpose since OpenGL uses column vector matrices // while we use row vector matrices... glMultMatrix(rotMatrix.transposed().ptr()); |
Categories: C++ Classes, Programming
