2014-12-30 2 views
0

기기 회전이 회전이없는 지점으로 캡처됩니다. 사용자가 ipad/iphone을 기울여서 새로운 각도가 5 도씩 점차 왼쪽/오른쪽으로 회전하는지 확인합니다. 어떤 점에서 나는 회전의 'jump'또는 gimbal lock을 본다. 점프가 발생하기 전에 점프가 정상적으로 느리게 진행됩니다. 어쩌면 벡터 또는 쿼터니온을 정상적으로 정규화하지 못하는 것일 수 있습니다. 어떻게 짐벌 잠금을하지 않고 부드러운 애니메이션을 달성하기 위해?특정 각도에서 점프 회전 (또는 짐벌 잠금) 문제가 발생했습니다.

-(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); 
    } 

나머지 코드는 위와 동일하게 유지되지만 여전히 회전 문제가 있습니다.

답변

0

긴 테스트 세션과 관찰 후에 짐벌 잠금이 없음을 알 수있었습니다. 수정 된 계산이 정확합니다.

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); 
    } 

문제는 애니메이션 체이닝과 기간이며, 나는 새로운 질문을해야합니다.

관련 문제