2016-11-24 20 views
1

CMAttitudeの四元数を使用してSceneKitカメラを回転させます。 また、四元数から抽出したY回転角度を使用する必要があります。 私はそれがロールになると予想しましたが、抽出後、Y回転角度は-90:90の範囲のピッチに対応します。 この範囲を0:180または0:360に変換するにはどうすればよいですか?GLKQuaternionから予期しないロールとピッチを抽出しました

- (SCNQuaternion)SCNQuaternionFromCMQuaternion:(CMQuaternion)q { 

    GLKQuaternion Q = GLKQuaternionMake(q.x, q.y, q.z, q.w); 
    GLKQuaternion xRotQ = GLKQuaternionMakeWithAngleAndAxis(-M_PI_2, 1, 0, 0); 
    Q = GLKQuaternionMultiply(xRotQ, Q); 

    double roll = atan2(2.0 * (Q.y * Q.z - Q.w * Q.x), 1.0 - 2.0 * (Q.x * Q.x + Q.y * Q.y)); // 0:180 but around X 

    double pitch = RADIANS_TO_DEGREES(asin(-2.0f * (Q.x * Q.z + Q.w * Q.y))); // 0:90 around Y 

    NSLog(@"%f", pitch); 
    // ... 

    CMQuaternion rq = {.x = Q.x, .y = Q.y, .z = Q.z, .w = Q.w}; 

    return SCNVector4Make(rq.x, rq.y, rq.z, rq.w); 
} 

答えて

1

私はこの方法を見つけた:

- (SCNQuaternion)SCNQuaternionFromCMQuaternion:(CMQuaternion)q { 

    GLKQuaternion Q = GLKQuaternionMake(q.x, q.y, q.z, q.w); 
    GLKQuaternion xRotQ = GLKQuaternionMakeWithAngleAndAxis(-M_PI_2, 1, 0, 0); 
    Q = GLKQuaternionMultiply(xRotQ, Q); 

    double gx = 2.0 * (Q.y * Q.w - Q.x * Q.z); 
    //double gy = 2.0 * (Q.x * Q.y + Q.z * Q.w); 
    double gz = Q.x * Q.x - Q.y * Q.y - Q.z * Q.z + Q.w * Q.w; 

    double pitch = RADIANS_TO_DEGREES(-asin(-2.0 * (Q.y * Q.w - Q.x * Q.z))); 

    if (gx >= 0 && gz < 0) 
     pitch = 180 - pitch; 
    else if (gx < 0 && gz < 0) 
     pitch = 180 - pitch; 
    else if (gx < 0 && gz >= 0) 
     pitch = 360 + pitch; 

    NSLog(@"%f", pitch); // now it has 0-360 range 

    CMQuaternion rq = {.x = Q.x, .y = Q.y, .z = Q.z, .w = Q.w}; 

    return SCNVector4Make(rq.x, rq.y, rq.z, rq.w); 
} 
関連する問題