Search code examples
iosrotationtransformquaternions

Rotating an object with quaternions


I'm trying to rotate an object in a 3d view using pans. There are 2 axes of rotation: the objects y-axis and a global fixed x-axis. Around the y axis i rotate simply using rotation matrices generated by method CATransform3DRotate and around fixed x-axis i use quaternions. Here i some code wich demonstrates the behaviour:

UITouch* touch   = [touches anyObject];
CGPoint location = [touch locationInView: viewController.view];
CGPoint lastLoc  = [touch previousLocationInView: viewController.view];
CGPoint diff     = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y);

float rotX = 1 * DEGREES_TO_RADIANS(diff.y / 4.0);
float rotY = -1 * DEGREES_TO_RADIANS(diff.x / 4.0);

CATransform3D m = glView.modelTransform;
if(fabs(diff.y)  >  fabs(diff.x) * 5.0) {  //up-down
    Vector3D xAxis = {1.0, 0.0, 0.0};
    Vector4D quaternion = [self makeQuaternionFromAxis: xAxis andAngle:rotX];
    Vector4D currentQuaterion = [self makeQuaternionFromRotationMatrix: m];
    quaternion = [self multiplyQuaternion:currentQuaterion buAnother:quaternion];
        m = [self makeRo
    tationMatrixFromQuaternion:quaternion];
        m = CATransform3DConcat(m, origin);
    }
else {                                    //right-left
    Vector3D yAxis = {0.0, 1.0, 0.0};
    m = CATransform3DRotate(m, rotY, yAxis.x, yAxis.y,yAxis.z);
}
glView.modelTransform = m;

I separate horizontal and vertical movement. The origin variable is original posiotion of the object in 3d view.The problem is that sometimes the object gets yaw angle rotation and and the rotation gets messed up and sometimes the object itself! This situation appears when i chaotically make pans on the screen. I tried to normalize the movement but this didnt helped me. Can someone tell me what i'm doing wrong.


Solution

  • Fixed code like this:

    Vector4D quaternion;
    if( fabs(diff.y) > fabs(diff.x) ) {  //up-down
        Vector3D xAxis = {1.0, 0.0, 0.0};
        quaternion = [self makeQuaternionFromAxis: xAxis andAngle:rotX];
        quaternion = [self multiplyQuaternion:quaternion buAnother:currentQuaterion];
        }
    else {                                    //right-left
        Vector3D yAxis = {0.0, 1.0, 0.0};
        quaternion = [self makeQuaternionFromRotationMatrix:CATransform3DMakeRotation(rotY, yAxis.x, yAxis.y,yAxis.z);
        quaternion = [self multiplyQuaternion:quaternion buAnother:currentQuaterion]
    }
    currentQuaterion = quaternion;
    glView.modelTransform = CATransform3DConcat([self makeRotationMatrixFromQuaternion:quaternion],perspective);
    

    currentQuaternion holds current object rotation.

    My summary: To multiply 'rotations' always use quaternions, and than transform tham into rotation matrix.