iPhone 5s上的偏航范围

时间:2014-07-31 09:43:18

标签: ios rotation quaternions motion pitch

我正在使用CMDeviceMotion和态度的四元数来获得音高偏航值,然后将这些值应用到Cocos3D场景中的CC3Camera以旋转相机

#define RadiansToDegrees(x) ((180 / M_PI) * x)

- (void)initializeScene
{
    //...

    CC3Camera *cam = [CC3Camera nodeWithName:@"Camera"];
    cam.location = cc3v(0, 10, 0.0001);
    cam.targetLocation = cc3v(0, 0, 0);
    _cameraBoom = [CC3Node nodeWithName:@"CameraBoom"];
    _cameraBoom.location = cc3v(0, 0, 0);
    [_cameraBoom addChild:cam];
    [self addChild:_cameraBoom];
    [self setActiveCamera:cam];
    _cameraBoom.rotation = cc3v(0, 90, 0);

    //...

    _motionManager = [[CMMotionManager alloc] init];
    _referenceAttitude = nil;
    _initialCameraRotation = _cameraBoom.rotation;

    [self enableMotion];
}

- (void)enableMotion
{
    CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
    _referenceAttitude = deviceMotion.attitude;
    _initialCameraRotation = _cameraBoom.rotation;

    [_motionManager startDeviceMotionUpdates];

    if (!_gyroTimer) {
        _gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1 / 30.0
                                                      target:self
                                                    selector:@selector(doGyroUpdate)
                                                    userInfo:nil
                                                     repeats:YES];
    }
}

- (void)doGyroUpdate
{
    CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
    CMAttitude *attitude = deviceMotion.attitude;

    if (_referenceAttitude != nil) {
        [attitude multiplyByInverseOfAttitude:_referenceAttitude];
    }

    CMQuaternion quat = attitude.quaternion;
    double pitch = RadiansToDegrees(atan2(2 * (quat.x * quat.w + quat.y * quat.z), 1 - 2 * (quat.x * quat.x + quat.z * quat.z)));
    double yaw = RadiansToDegrees(asin(2 * (quat.x * quat.y + quat.w * quat.z)));

    _cameraBoom.rotation = CC3VectorAdd(_initialCameraRotation, cc3v(pitch, yaw, 0));
}

音高在[-π,π]范围内。当设备面朝上时,音高= 0,当我从桌子上取下设备并指向它拍照时(纵向模式),它变为π/ 2。 [-π,π]范围使我能够将设备旋转360°。面朝下时(即设备颠倒),音高值为π。

偏航范围仅为[-π/ 2,π/ 2]。它从0开始,当我向左旋转设备时,它变为π/ 2。但如果我将其旋转超过π/ 2,则偏航值开始减小。

我可以获得范围[-π,π]中的偏航值,就像俯仰一样吗?能够将摄像机侧向旋转180°(左侧)会更有用在右边,有一个完整的360°视图)而不是垂直翻转设备,以便用相机看后面。

1 个答案:

答案 0 :(得分:0)

以下是我最终使用内置函数完成的工作:

- (void)doGyroUpdate
{
    CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
    CMAttitude *attitude = deviceMotion.attitude;

    if (_referenceAttitude != nil) {
        [attitude multiplyByInverseOfAttitude:_referenceAttitude];
    }

    CMQuaternion quat = attitude.quaternion;
    CC3Quaternion cc3Quat = CC3QuaternionMake(quat.x, quat.y, quat.z, quat.w);
    CC3Vector rot = CC3RotationFromQuaternion(cc3Quat);

    _cameraBoom.rotation = cc3v(-rot.x, -rot.z, rot.y);
}

结果:

像这样旋转相机使您可以环顾天空盒,就像通常通过设备的后置摄像头看世界一样。我的CC3Camera对象位于一个球体内部,内部有一个HDRi图像映射到它上面(参见this帖子)。

平滑旋转相机:

[_cameraBoom runAction:[CC3ActionRotateTo actionWithDuration:0.15 rotateTo:cc3v(-rot.x, -rot.z, rot.y)]];

希望这也有助于其他人。