Help on learning how to implement an Arcball style rotation
in
Contributed Library Questions
•
1 year ago
Hi,
I know its been done before and you may say why trying to reinvent the wheel, but I want to learn how to do it by my self so I'm trying to duplicate the functionality of the Arcball class found in the P5 wiki page, I believe I got the bare bone methods to get it working but I'm getting a very weird behaviour
Here is the code:
- import toxi.geom.*;
- int axis;
- float radius;
- Vec3D center;
- Vec3D v_down, v_drag;
- Vec3D[] axisSet;
- Quaternion q_now, q_down, q_drag;
- void setup() {
- size( 640, 480, P3D );
- // smooth();
- float x = width / 2.0f;
- float y = height / 2.0f;
- float z = min( x, y );
- center = new Vec3D( x, y, z );
- radius = -z;
- v_down = new Vec3D();
- v_drag = new Vec3D();
- q_now = new Quaternion();
- q_down = new Quaternion();
- q_drag = new Quaternion();
- axisSet = new Vec3D[] { new Vec3D(1, 0, 0), new Vec3D(0, 1, 0), new Vec3D(0, 0, 1) };
- axis = -1;
- }
- void draw() {
- background( 200 );
- q_now = q_drag.multiply( q_down );
- pushMatrix();
- translate( center.x, center.y, center.z );
- rotate( q_now.w, q_now.x, q_now.y, q_now.z );
- // translate( -center.x, -center.y, -center.z );
- // Draw down vector
- stroke( 255, 255, 0 );
- line( center.x, center.y, center.z, v_down.x, v_down.y, v_down.z );
- // Draw drag vector
- stroke( 255, 0, 0 );
- line( center.x, center.y, center.z, v_drag.x, v_drag.y, v_drag.z );
- stroke( 60 );
- noFill();
- box( 160 );
- popMatrix();
- }
- void mousePressed() {
- v_down = mouseToSphere( mouseX, mouseY );
- q_down.set( q_now );
- q_drag.set( 1, 0, 0, 0 );
- }
- void mouseDragged() {
- v_drag = mouseToSphere( mouseX, mouseY );
- q_drag.set( v_down.dot( v_drag ), v_down.cross( v_drag ) );
- }
- Vec3D mouseToSphere( float x, float y ) {
- Vec3D v = new Vec3D();
- v.x = (x - center.x) / radius;
- v.y = (y - center.y) / radius;
- v.z = 0;
- float mag = (v.x * v.x) + (v.y * v.y);
- if ( mag > 1.0f ) {
- v.normalize();
- }
- else {
- v.z = sqrt( 1.0f - mag );
- }
- println( v );
- return (axis == -1) ? v : constrainVector( v, axisSet[axis] );
- }
- Vec3D constrainVector( Vec3D vector, Vec3D axis ) {
- Vec3D res = new Vec3D();
- Vec3D temp = axis.scale( axis.dot( vector ) );
- temp.subSelf( vector );
- res.sub( temp );
- res.normalize();
- return res;
- }
I'm looking at all sorts of arcball implementations but I can't see what is wrong with mine, any help will be much appreciated!
1