ios - 从 GLKQuaternion 中提取的意外滚动和俯仰

标签 ios scenekit quaternions core-motion

我使用 CMAttitude 中的四元数来旋转 SceneKit 相机。 我还需要使用从四元数中提取的 Y 旋转角度。 我预计它会滚动,但提取后 Y 旋转角度对应于具有 -90:90 范围的间距。 如何将此范围转换为 0:180 或 0:360?

- (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);
}

最佳答案

我是这样找到的:

- (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);
}

关于ios - 从 GLKQuaternion 中提取的意外滚动和俯仰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40793949/

相关文章:

ios - 如何从 superview 获取所有元素(如 : UiLabel, UITextfield)并设置标签文本颜色和文本字段占位符颜色

iOS 表格标题和单元格之间的快速边距

ios - 以编程方式更改 SCNScene 的 sceneNamed

ios - iOS 14 解决方案中的 SceneKit Metal 着色器编译性能错误

c++ - 使用四元数围绕轴旋转 vector

ios - 如何更改ios中特定单词的颜色

objective-c - IAP 问题 - response.products 数组中没有产品

swift - 如何使物体随机产生在一个地方并在产生后向一个方向移动

system - 将表示从一个坐标系旋转到另一个坐标系的四元数转换

c++ - 使用四元数进行OpenGL旋转