Преобразование портретных углов CoreMotion в альбомную ориентацию вправо и влево в Objective-C iOS - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь заставить CoreMotion работать правильно, когда устройство пользователя находится в ландшафтном режиме.Приведенный ниже код работает для портретного режима, но я не могу понять, как преобразовать его в альбомную левую и альбомную правую.Если вы знакомы с Quaternions и CoreMotion, любая помощь будет принята с благодарностью.

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

Я использую кватерион для переменной рыскания, потому что истинное «рыскание» от позиции, кажется,например, если телефон держался ровно.

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

    // set content offset for image inside scrollview
    CGFloat offsetX;
    if (self.deviceDegreesZ >= 180) {
       offsetX = (_maximumXOffset/2) + (_maximumXOffset/2) * (fabs(self.deviceDegreesZ - 180))/90;
    } else {
       offsetX = (_maximumXOffset/2) - (_maximumXOffset/2) * (fabs(self.deviceDegreesZ - 180))/90;
    }

     CGFloat offsetY;
     if (self.deviceDegreesY >= 90) {
         offsetY = (_maximumYOffset/2) + (_maximumYOffset/2) * (fabs(self.deviceDegreesY - 90))/45;
     } else {
         offsetY = (_maximumYOffset/2) - (_maximumYOffset/2) * (fabs(self.deviceDegreesY - 90))/45;
     }

    if (offsetX != 0 && offsetY != 0) {
        [_scrollView setContentOffset:CGPointMake(offsetX, offsetY) animated:NO];
    }


    // device angles used to set content offset above and look at imageview
    // Quaternion
    CMQuaternion quat = self.motionManager.deviceMotion.attitude.quaternion;
    int thePitch = self.motionManager.deviceMotion.attitude.pitch * (180.0 / M_PI);
    int theRoll = self.motionManager.deviceMotion.attitude.roll * (180.0 / M_PI);
    int theYaw = radiansToDegrees(asin(2*(quat.x*quat.z - quat.w*quat.y)));

    // gravity
    CMAcceleration gravity = self.motionManager.deviceMotion.gravity;
    double rotation = atan2(gravity.x, gravity.y) - M_PI;
    self.imageView.transform = CGAffineTransformMakeRotation(rotation);

    // portrait (working)
    if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationPortrait){

        // X
        if (quat.y >= 0.5f) {
            self.deviceDegreesZ = radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
        } else if (quat.y <= -0.5f) {
            self.deviceDegreesZ = 360 + radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
        } else {
            self.deviceDegreesZ = 180 - radiansToDegrees(asin(2*quat.x*quat.y + 2*quat.w*quat.z));
        }

        // Y
        CMAcceleration gravity = self.motionManager.deviceMotion.gravity;
        if (gravity.z >= 0) {
            self.deviceDegreesY = thePitch; // - abs(theYaw)
        } else {
            self.deviceDegreesY = 180.f - thePitch; //  - abs(theYaw)
        }
    }

    // landscape left
    if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationLandscapeLeft){
        // ???
    }

    // landscape right
    if ([[UIDevice currentDevice]orientation] == UIInterfaceOrientationLandscapeRight){
        // ???
    }
...