我将设备的旋转捕获为不发生旋转的静止点。用户倾斜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);
}
其余代码仍然如上所示,但我仍然看到轮换故障。
答案 0 :(得分: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);
}
问题是动画链和持续时间,我不得不在新问题中提出。