【问题标题】:issue with jumping rotation (or gimbal lock) at certain angle以特定角度跳跃旋转(或万向节锁定)的问题
【发布时间】:2015-02-26 15:17:30
【问题描述】:

我正在捕捉设备的旋转作为不发生旋转的静止点。在用户倾斜 ipad/iphone 后,我检查新角度以 5 度增量向左/向右旋转。在某些时候,我看到一个“跳跃”或旋转的万向节锁定。在跳跃发生之前,跳跃发生的速度比平时慢。也许我没有正确规范化向量或四元数。如何在没有云台锁的情况下实现流畅的动画?

-(void) awakeFromNib
{
  tmp = GLKQuaternionIdentity;
  self.motionManager = [[CMMotionManager alloc] init];
  self.motionManager.deviceMotionUpdateInterval = 1.0/60.0;

  [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
      if (error == nil && onceSampled == NO)
      {
             onceSampled = YES;
             roll = GLKMathRadiansToDegrees(atan2(2*(startingQuaternion.y*startingQuaternion.w - startingQuaternion.x*startingQuaternion.z), 1 - 2*startingQuaternion.y*startingQuaternion.y - 2*startingQuaternion.z*startingQuaternion.z)) ;
             pitch = GLKMathRadiansToDegrees(atan2(2*(startingQuaternion.x*startingQuaternion.w + startingQuaternion.y*startingQuaternion.z), 1 - 2*startingQuaternion.x*startingQuaternion.x - 2*startingQuaternion.z*startingQuaternion.z));
             yaw = GLKMathRadiansToDegrees(asin(2*startingQuaternion.x*startingQuaternion.y + 2*startingQuaternion.w*startingQuaternion.z));
      }
   }];
}

- (void)renderer:(id<SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time
{
   tmp.x = self.motionManager.deviceMotion.attitude.quaternion.x ;
   tmp.y = self.motionManager.deviceMotion.attitude.quaternion.y ;
   tmp.z = self.motionManager.deviceMotion.attitude.quaternion.z ;
   tmp.w = self.motionManager.deviceMotion.attitude.quaternion.w;

   double myRoll = GLKMathRadiansToDegrees(atan2(2*(tmp.y*tmp.w - tmp.x*tmp.z), 1 - 2*tmp.y*tmp.y - 2*tmp.z*tmp.z)) ;
   double myPitch = GLKMathRadiansToDegrees(atan2(2*(tmp.x*tmp.w + tmp.y*tmp.z), 1 - 2*tmp.x*tmp.x - 2*tmp.z*tmp.z));
   double myYaw = GLKMathRadiansToDegrees(asin(2*tmp.x*tmp.y + 2*tmp.w*tmp.z));

   SCNQuaternion oldRotScnQuat = _cameraNode.presentationNode.rotation;
   GLKQuaternion glQuatOldRot = GLKQuaternionMakeWithAngleAndAxis(oldRotScnQuat.w, oldRotScnQuat.x, oldRotScnQuat.y, oldRotScnQuat.z);

   GLKQuaternion netRotY = GLKQuaternionIdentity;

   if(myPitch >= pitch + 1 || myPitch <= pitch - 1)
    {
        int dir = myPitch > pitch ? 1: -1;
        GLKVector3 vec = GLKVector3Normalize(GLKVector3Make(0, dir, 0));
        netRotY = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(5), vec.x, vec.y , vec.z);
    }
    glQuatOldRot = GLKQuaternionMultiply(glQuatOldRot, netRotY);
    axis = GLKQuaternionAxis(glQuatOldRot);
    angle = GLKQuaternionAngle(glQuatOldRot);

    [_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(axis.x, axis.y, axis.z, angle) duration:1.2]];
}

编辑:实际上,如果设备从静止点向左/向右或向上/向下倾斜,我想同时在 X 和 Y 上旋转。如果有人可以解释它会很棒。

编辑:我一直在努力让它工作。当我阅读更多关于四元数的信息时,我发现我在创建四元数时犯了一个错误。我想正确的方法应该是:

if(myPitch >= pitch + 1 || myPitch <= pitch - 1)
 {
   int angle = myPitch > pitch ? 5: -5; // left or right tilt
   GLKVector3 vec = GLKVector3Normalize(GLKVector3Make(0, 1, 0));//rotate on y-axis (-1) is wrong
   double result = sinf(GLKMathDegreesToRadians(angle)/2);
   netRotY = GLKQuaternionMakeWithAngleAndAxis(cosf(GLKMathDegreesToRadians(angle)/2), vec.x *result, vec.y * result, vec.z * result);
   netRotY = GLKQuaternionNormalize(netRotY);
  }

其余代码仍然如上,但我仍然看到旋转出现故障。

【问题讨论】:

    标签: ios rotation quaternions scenekit


    【解决方案1】:

    经过长时间的测试和观察,我发现没有云台锁。我编辑的计算是正确的:

    if(myPitch >= pitch + 1 || myPitch <= pitch - 1)
     {
       int angle = myPitch > pitch ? 5: -5; // left or right tilt
       GLKVector3 vec = GLKVector3Normalize(GLKVector3Make(0, 1, 0));//rotate on y-axis (-1) is wrong
       double result = sinf(GLKMathDegreesToRadians(angle)/2);
       netRotY = GLKQuaternionMakeWithAngleAndAxis(cosf(GLKMathDegreesToRadians(angle)/2), vec.x *result, vec.y * result, vec.z * result);
       netRotY = GLKQuaternionNormalize(netRotY);
      }
    

    问题是动画链接和持续时间,我必须在新问题中提出。

    【讨论】:

      猜你喜欢
      • 2018-11-24
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 2020-04-24
      相关资源
      最近更新 更多