【问题标题】:keep rotating scene node until the device gets back to starting position继续旋转场景节点,直到设备回到起始位置
【发布时间】: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

以下几点很重要:

  1. 具有不发生旋转的静止方向
  2. 当设备倾斜时,然后逐渐旋转
  3. 通过实现上述几点,用户无需翻转设备即可获得完整的旋转 :-)

我不知道如何实现这一点。非常感谢任何帮助。

编辑:添加一些代码尝试实现 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


【解决方案1】:

要跟踪静止方向,您需要跟踪您采样的第一个 CMAttitude。然后您可以使用multiplyByInverseOfAttitude: 获取每次采样时该态度与当前态度之间的差异。 (如果由于过滤而已经在使用四元数,则可以使用 GLKQuaternionInvertGLKQuaternionMultiply 执行等效操作。)

要进行您所说的增量旋转,使用欧拉角可能是最简单的 - 相对于您刚刚发现的态度差异,因此零滚动意味着用户开始的中性方向没有变化in(无论该方向是什么,都是绝对术语)。然后,当滚动角在给定时间步长内为正时(例如,在您的 SCNSceneRendererDelegate 更新方法中),您可以增加相机节点的滚动,反之亦然。

事实上,如果您以这种方式进行增量轮换,您可能不需要过滤步骤(来自您链接到的我的其他答案)。相反,您可能可以摆脱原始姿态输入和阈值。例如,仅当姿态的滚动大于 5 度时才增加节点的滚动。在这种情况下,您可以从CMAttitude(与本答案前面的不同态度)获得欧拉角,而不必担心自己从四元数中提取欧拉角(not that it's all that hard)。

【讨论】:

  • 我有点期待你会回答我的问题 :-) 我会根据你的建议用欧拉角来实现它。我可能有后续问题。非常感谢。
  • 我已经添加了一些代码和后续问题。你可以看看吗?
猜你喜欢
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
相关资源
最近更新 更多