1

我目前正在研究增强现实,为此我想使用陀螺仪和核心运动。我研究了 Apple pARk示例代码,我了解我花时间阅读文档的大部分数学知识,因为乍一看并不清楚!一切都很好,直到我尝试让它在横向模式下工作。

我不会在这里解释所有的理论,这太长了。但是对于那些经历过的人来说,我的问题是,我们采用姿态的旋转矩阵来将此旋转应用于我们的坐标。好的,到这里为止都很好,但 Core Motion 似乎无法使其适应横向模式。我在这个主题上看到了类似的问题,但似乎没有人有解决方案。

所以我试着自己做,这是我的想法:

每次我们将设备旋转到横向时,都会进行 +-90° 的旋转(取决于横向左或右)。我决定创建一个 4X4 旋转矩阵来应用这种旋转。然后乘以cameraTransform矩阵(姿态的3X3 CMRotationMatrix到4X4的自适应),我们得到矩阵cameraTransformRotated:

- (void)createMatLandscape{
switch(cameraOrientation){
    case UIDeviceOrientationLandscapeLeft:
        landscapeRightTransform[0] = cos(degreesToRadians(90));
        landscapeRightTransform[1] = -sin(degreesToRadians(90));
        landscapeRightTransform[2] = 0;
        landscapeRightTransform[3] = 0;

        landscapeRightTransform[4] = sin(degreesToRadians(90));
        landscapeRightTransform[5] = cos(degreesToRadians(90));
        landscapeRightTransform[6] = 0;
        landscapeRightTransform[7] = 0;

        landscapeRightTransform[8] = 0;
        landscapeRightTransform[9] = 0;
        landscapeRightTransform[10] = 1;
        landscapeRightTransform[11] = 0;

        landscapeRightTransform[12] = 0;
        landscapeRightTransform[13] = 0;
        landscapeRightTransform[14] = 0;
        landscapeRightTransform[15] = 1;

        multiplyMatrixAndMatrix(cameraTransformRotated, cameraTransform, landscapeRightTransform);
        break;
    case UIDeviceOrientationLandscapeRight:
        landscapeLeftTransform[0] = cos(degreesToRadians(-90));
        landscapeLeftTransform[1] = -sin(degreesToRadians(-90));
        landscapeLeftTransform[2] = 0;
        landscapeLeftTransform[3] = 0;

        landscapeLeftTransform[4] = sin(degreesToRadians(-90));
        landscapeLeftTransform[5] = cos(degreesToRadians(-90));
        landscapeLeftTransform[6] = 0;
        landscapeLeftTransform[7] = 0;

        landscapeLeftTransform[8] = 0;
        landscapeLeftTransform[9] = 0;
        landscapeLeftTransform[10] = 1;
        landscapeLeftTransform[11] = 0;

        landscapeLeftTransform[12] = 0;
        landscapeLeftTransform[13] = 0;
        landscapeLeftTransform[14] = 0;
        landscapeLeftTransform[15] = 1;

        multiplyMatrixAndMatrix(cameraTransformRotated, cameraTransform, landscapeLeftTransform);
        break;
    default:
        cameraTransformRotated[0] = cameraTransform[0];
        cameraTransformRotated[1] = cameraTransform[1];
        cameraTransformRotated[2] = cameraTransform[2];
        cameraTransformRotated[3] = cameraTransform[3];

        cameraTransformRotated[4] = cameraTransform[4];
        cameraTransformRotated[5] = cameraTransform[5];
        cameraTransformRotated[6] = cameraTransform[6];
        cameraTransformRotated[7] = cameraTransform[7];

        cameraTransformRotated[8] = cameraTransform[8];
        cameraTransformRotated[9] = cameraTransform[9];
        cameraTransformRotated[10] = cameraTransform[10];
        cameraTransformRotated[11] = cameraTransform[11];

        cameraTransformRotated[12] = cameraTransform[12];
        cameraTransformRotated[13] = cameraTransform[13];
        cameraTransformRotated[14] = cameraTransform[14];
        cameraTransformRotated[15] = cameraTransform[15];

        break;
}
}

然后就在我们更新所有要点之前,我这样做:

multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransformRotated);

之后其余代码保持不变,我只希望注释以横向正确显示。现在这是我唯一的想法,横向渲染不好,我将设备向右或向左移动,注释向下或向上(就像我没有添加此代码时一样)。

有没有人提出解决方案?我将继续搜索,尤其是在 CMRotationMatrix 上,它似乎不是典型的旋转矩阵,我找不到任何文档准确说明该矩阵的不同元素是什么。

4

1 回答 1

2

I just managed to adapt this (Apple's pARk sample) to landscape (right) yesterday and would like to share the changes made. It appears to work correctly, but please call out any mistakes. This only supports landscape right but can probably be adapted easily for left.

In ARView.m,

In -(void)initialize, switch the bounds height and width

createProjectionMatrix(projectionTransform, 60.0f*DEGREES_TO_RADIANS, self.bounds.size.height*1.0f / self.bounds.size.width, 0.25f, 1000.0f);

In -(void)startCameraPreview

[captureLayer setOrientation:AVCaptureVideoOrientationLandscapeRight];

In -(void)drawRect:

//switch x and y
float y = (v[0] / v[3] + 1.0f) * 0.5f; 
float x = (v[1] / v[3] + 1.0f) * 0.5f;

poi.view.center = CGPointMake(self.bounds.size.width-x*self.bounds.size.width, self.bounds.size.height-y*self.bounds.size.height); //invert x
于 2013-01-04T19:31:01.813 回答