【发布时间】:2015-02-24 20:38:09
【问题描述】:
在尝试使用场景工具包时,我使用 self.motionManager.deviceMotion.attitude.quaternion 在 3D 场景中旋转场景节点(相机)。假设用户启动应用程序并且设备以某种方式倾斜,因此该起始方向应计为静止点,并且在此位置时不应发生旋转。当用户倾斜设备(左 右和/或上 下)时,它应该逐渐旋转,直到用户将设备放回不会发生旋转的开始/静止方向。 According to this answer I know how to filter the noise and random jiggling
以下几点很重要:
- 具有不发生旋转的静止方向
- 当设备倾斜时,然后逐渐旋转
- 通过实现上述几点,用户无需翻转设备即可获得完整的旋转 :-)
我不知道如何实现这一点。非常感谢任何帮助。
编辑:添加一些代码尝试实现 rickster 的回答
我必须在startDeviceMotionUpdatesToQueue:withHandler: 中获取滚动、偏航、俯仰值,否则它们都为零
-(void) awakeFromNib
{
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)
{
if (firstValue == NO)
{
firstValue = YES;
yaw = self.motionManager.deviceMotion.attitude.yaw;
roll = self.motionManager.deviceMotion.attitude.roll;
pitch = self.motionManager.deviceMotion.attitude.pitch;
}
}
}];
}
为了简单起见,我尝试先在 x 轴上旋转 5 度:
- (void)renderer:(id<SCNSceneRenderer>)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)time
{
currentYaw = self.motionManager.deviceMotion.attitude.yaw;
currentRoll = self.motionManager.deviceMotion.attitude.roll;
currentPitch = self.motionManager.deviceMotion.attitude.pitch;
SCNVector4 q =_cameraNode.presentationNode.rotation;
float phi = atan((2*(q.x*q.y + q.z*q.w))/(1-2*(pow(q.y,2)*pow(q.z,2))));
if (currentRoll > 0)
{
[_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(1, 0, 0, ( phi + DEGREES_TO_RADIANS(5))) duration:1]];
}
else if(currentRoll < 0 )
{
[_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(1, 0, 0, (phi - DEGREES_TO_RADIANS(5))) duration:1]];
}
}
变量的调试输出是:
调试:q = (x = 0.999998092, y = 0, z = 0, w = -0.0872662216)
phi = 0
currentRoll = -1.1897298305515105
它实际上根本不旋转。 phi 值看起来不太好。我做错了什么?
旁注:如何一次对所有轴进行旋转?将四元数 oldRotation 与 x 然后 y 然后 z 相乘?顺序正确吗?
【问题讨论】:
-
只是想指出上面代码中的旋转存在很大缺陷。
标签: ios rotation quaternions core-motion scenekit