title: Arcball Rotation with Quaternions (using iOS GLKit)
body: <p>I'm looking for a simple implementation for arcball rotation on 3D models with quaternions, <strong>specifically using GLKit on iOS</strong>. So far, I have examined the following sources:</p>
  
  <ul>
  <li><a href="http://thestrangeagency.com/arcball-rotation-with-glkit/" rel="nofollow">Arcball rotation with GLKit</a></li>
  <li><a href="http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl" rel="nofollow">How to rotate a 3D object with touches using OpenGL</a></li>
  </ul>
  
  <p>I've also been trying to understand source code and maths from <a href="http://www.idevgames.com/articles/quaternions" rel="nofollow">here</a> and <a href="http://ofps.oreilly.com/titles/9780596804824/" rel="nofollow">here</a>. I can rotate my object but it keeps jumping around at certain angles, so I fear gimbal lock is at play. I'm using gesture recognizers to control the rotations (pan gestures affect roll and yaw, rotate gestures affect pitch). I'm attaching my code for the quaternion handling as well as the modelview matrix transformation.</p>
  
  <p>Variables:</p>
  
  <ul>
  <li><code>GLKQuaternion rotationE;</code></li>
  </ul>
  
  <p>Quaternion Handling:</p>
  
  <pre><code>- (void)rotateWithXY:(float)x and:(float)y
  {
      const float rate = M_PI/360.0f;
      GLKVector3 up = GLKVector3Make(0.0f, 1.0f, 0.0f);
      GLKVector3 right = GLKVector3Make(1.0f, 0.0f, 0.0f);
  
      up = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), up);
      self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(x*rate, up));
  
      right = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), right);
      self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(y*rate, right));
  }
  
  - (void)rotateWithZ:(float)z
  {
      GLKVector3 front = GLKVector3Make(0.0f, 0.0f, -1.0f);
  
      front = GLKQuaternionRotateVector3(GLKQuaternionInvert(self.rotationE), front);
      self.rotationE = GLKQuaternionMultiply(self.rotationE, GLKQuaternionMakeWithAngleAndVector3Axis(z, front));
  }
  </code></pre>
  
  <p>Modelview Matrix Transformation (Inside Draw Loop):</p>
  
  <pre><code>// Get Quaternion Rotation
  GLKVector3 rAxis = GLKQuaternionAxis(self.transformations.rotationE);
  float rAngle = GLKQuaternionAngle(self.transformations.rotationE);
  
  // Set Modelview Matrix
  GLKMatrix4 modelviewMatrix = GLKMatrix4Identity;
  modelviewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -0.55f);
  modelviewMatrix = GLKMatrix4Rotate(modelviewMatrix, rAngle, rAxis.x, rAxis.y, rAxis.z);
  modelviewMatrix = GLKMatrix4Scale(modelviewMatrix, 0.5f, 0.5f, 0.5f);
  glUniformMatrix4fv(self.sunShader.uModelviewMatrix, 1, 0, modelviewMatrix.m);
  </code></pre>
  
  <p>Any help is greatly appreciated, but I do want to keep it as simple as possible and stick to GLKit.</p>