Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 继续旋转场景节点,直到设备回到起始位置_Ios_Rotation_Quaternions_Core Motion_Scenekit - Fatal编程技术网

Ios 继续旋转场景节点,直到设备回到起始位置

Ios 继续旋转场景节点,直到设备回到起始位置,ios,rotation,quaternions,core-motion,scenekit,Ios,Rotation,Quaternions,Core Motion,Scenekit,在使用场景工具包进行实验时,我使用self.motionManager.deviceMotion.attitude.quaternion在3D场景中旋转场景节点(摄影机)。假设用户启动应用程序时,设备以某种方式倾斜,因此该启动方向应算作静止点,并且在该位置时不应发生旋转。当用户倾斜设备(左右和/或上下)时,设备应逐渐旋转,直到用户将设备放回起始/静止方向,此时不会发生旋转 以下几点很重要: 有一个静止的方向,没有旋转发生 当设备倾斜时,然后逐渐旋转 通过实现上述各点,用户无需翻转设备即可完成旋转

在使用场景工具包进行实验时,我使用
self.motionManager.deviceMotion.attitude.quaternion
在3D场景中旋转场景节点(摄影机)。假设用户启动应用程序时,设备以某种方式倾斜,因此该启动方向应算作静止点,并且在该位置时不应发生旋转。当用户倾斜设备(左右和/或上下)时,设备应逐渐旋转,直到用户将设备放回起始/静止方向,此时不会发生旋转

以下几点很重要:

  • 有一个静止的方向,没有旋转发生
  • 当设备倾斜时,然后逐渐旋转
  • 通过实现上述各点,用户无需翻转设备即可完成旋转:-)
  • 我不知道如何做到这一点。非常感谢您的帮助

    编辑:添加一些代码试图实现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]];
      }
    
    }
    
    -(void)渲染器:(id)aRenderer didSimulatePhysicsAtTime:(NSTimeInterval)时间
    {
    currentYaw=self.motionManager.deviceMotion.姿态.yaw;
    currentRoll=self.motionManager.deviceMotion.姿态.roll;
    currentPitch=self.motionManager.deviceMotion.姿态.pitch;
    SCInvector4 q=\u cameraNode.presentationNode.rotation;
    浮点数phi=atan((2*(q.x*q.y+q.z*q.w))/(1-2*(功率(q.y,2)*功率(q.z,2));
    如果(当前滚动>0)
    {
    [_cameraNode运行动作:[SCNAction rotateToAxisAngle:scInvector4Make(1,0,0,(φ+度到弧度(5)))持续时间:1];
    }
    否则如果(当前滚动<0)
    {
    [_cameraNode运行动作:[SCNAction rotateToAxisAngle:scInvector4Make(1,0,0,(φ-度到弧度(5)))持续时间:1];
    }
    }
    
    变量的调试输出为:

    调试:q=(x=0.99999092,y=0,z=0,w=-0.0872662216)

    φ=0

    currentRoll=-1.18972983055105

    它实际上根本不旋转。phi值看起来不太好。我做错了什么


    旁注:如何一次旋转所有轴?将四元数oldRotation与x、y、z相乘?这是正确的顺序吗?

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

    要进行你所说的增量旋转,可能最容易使用欧拉角——相对于你刚刚发现的姿态差,因此零的滚动意味着用户开始时的中性方向没有变化(不管该方向是绝对方向)。然后,当滚动角度在给定的时间步长内为正时(例如,在
    SCNSceneRendererDelegate
    update方法中),可以增加摄影机节点的滚动,反之亦然


    事实上,如果您以这种方式进行增量旋转,您可能不需要过滤步骤(来自您链接到的我的另一个答案)。相反,您可能可以通过原始姿态输入和阈值逃脱惩罚。例如,仅当姿态的横摇大于5度时,才增加节点的横摇。在这种情况下,您可以从
    Cmatitude
    (与本答案前面的不同态度)中获得Euler角,而不必担心自己从四元数中提取Euler角()。

    我有点希望您能回答我的问题:-)我将根据您对Euler角的建议来实现它。我可能有后续问题。非常感谢。我已经添加了一些代码和后续问题。你能看一下吗?只是想指出上面代码中的旋转有很大的缺陷。