Использование кватерниона вместо крена, тангажа и рыскания для отслеживания движения устройства

Пожалуйста, примите мой длинный вопрос, я пытаюсь сделать его как можно более понятным.

То, что я пытаюсь сделать, это получить ориентацию (шаг крена и рыскание), когда снимок сделан с помощью камеры, а затем сохранить значения ориентации в nsuserdefaults. После сохранения ориентация меняется, а затем попробуйте привести телефон в то же положение, в котором был сделан снимок, постоянно сравнивая значения положения (сохраненные и текущие).

Для целей интерфейса пользовательский интерфейс имеет 3 точки (по одной для каждого параметра ориентации) на экране, которые указывают правильную ориентацию, на которой был сделан снимок. При достижении правильного положения на экране отображается флаг матча.

Я нашел значения крена, тангажа и рыскания как:

CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
myRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ;
myPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z));
myYaw = radiansToDegrees(2*(quat.x*quat.y + quat.w*quat.z));

Когда я заметил, что есть некоторые различия в значениях рыскания, я искал и мог найти здесь:ссылка на сайт, тот

рыскание, тангаж и крен от кватерниона, у вас возникнет та же проблема, что и при использовании только рыскания, тангажа и крена. Вы должны использовать кватернионыВЕЗДЕ в вашем коде и забудьте о рыскании

Так что теперь я думаю, что мне нужно снова все кодировать ... Пожалуйста, не могли бы вы указать мне пример кода для использованиякватернион для этого?

Вот код, над которым я работаю:

В ViewController.m, внутри изображения: didFinishSavingWithError:

[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {

        CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
        double tempYaw = radiansToDegrees(asin(2*(quat.x*quat.y + quat.w*quat.z)));
        double tempRoll = radiansToDegrees(atan2(2*(quat.y*quat.w - quat.x*quat.z), 1 - 2*quat.y*quat.y - 2*quat.z*quat.z)) ;
        double tempPitch = radiansToDegrees(atan2(2*(quat.x*quat.w + quat.y*quat.z), 1 - 2*quat.x*quat.x - 2*quat.z*quat.z));

        if (savingGyroOrientation == YES) {

            NSLog(@"Roll = %f degrees",tempRoll);
            NSLog(@"Pitch = %f degrees",tempPitch);
            NSLog(@"Yaw = %f degrees",tempYaw);

            [self.deviceStatus setDouble:tempRoll forKey:@"DeviceRoll"];
            [self.deviceStatus setDouble:tempPitch forKey:@"DevicePitch"];
            [self.deviceStatus setDouble:tempYaw forKey:@"DeviceYaw"];
            [self.deviceStatus synchronize];

            savingGyroOrientation = NO;
            checkingGyroOrientation = YES;
            self.savingLabel.hidden = YES;
            self.startTimerButton.hidden = NO;

        }
        savingGyroOrientation = NO;
        checkingGyroOrientation = YES;
        self.savingLabel.hidden = YES;
        self.startTimerButton.hidden = NO;
    }

     if (timerRunning == YES) {
         if (checkingGyroOrientation == YES) {

             self.takePicButton.hidden = YES;

             int xRoll, yPitch, xYaw, yYaw;
             // Roll Checking
             if (tempRoll >= [self.deviceStatus doubleForKey:@"DeviceRoll"]-1 && tempRoll  180){
                     xRoll = 150 + (tempRoll - [self.deviceStatus doubleForKey:@"DeviceRoll"]-360);
                     self.rollToR.hidden = YES;
                     if (xRoll =300){
                         [self.rollToL setFrame:CGRectMake(300, 195, 20, 20)];
                     }else{
                         [self.rollToL setFrame:CGRectMake(xRoll, 195, 20, 20)];
                     }
                 }
                 if (tempRoll - [self.deviceStatus doubleForKey:@"DeviceRoll"] < -180){
                     xRoll = 150 + (tempRoll - [self.deviceStatus doubleForKey:@"DeviceRoll"]+360);
                     self.rollToL.hidden = YES;
                     if (xRoll = 300){
                         [self.rollToR setFrame:CGRectMake(300, 195, 20, 20)];
                     }else{
                         [self.rollToR setFrame:CGRectMake(xRoll, 195, 20, 20)];
                     }
                 }
             }
             //Pitch Checking
             if (tempPitch >= [self.deviceStatus doubleForKey:@"DevicePitch"]-1 && tempPitch 

Ответы на вопрос(2)

Ваш ответ на вопрос