【问题标题】:Using Core Motion in landscape mode在横向模式下使用 Core Motion
【发布时间】:2012-11-17 16:08:43
【问题描述】:

我目前正在研究增强现实,为此我想使用陀螺仪和 Core Motion。我研究了 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 上,它似乎不是典型的旋转矩阵,我找不到任何文档准确说明该矩阵的不同元素是什么。

【问题讨论】:

标签: ios augmented-reality core-motion


【解决方案1】:

我昨天刚刚设法将这个(Apple 的公园示例)改编为景观(右),并想分享所做的更改。它似乎工作正常,但请指出任何错误。这仅支持横向右侧,但可能很容易适应左侧。

在 ARView.m 中,

在-(void)initialize中,切换边界高度和宽度

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

在 -(void)startCameraPreview 中

[captureLayer setOrientation:AVCaptureVideoOrientationLandscapeRight];

在 -(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

【讨论】:

  • 哇,谢谢你的分享!!我会试一试,让你知道;)
  • 对不起,我最近很忙 :) 是的,它很好地支持景观,感谢您的努力,但我担心它在数学上是错误的,我的第一个解决方案也是错误的。我们刚刚切换了变量。一个好的解决方案是重新映射设备坐标系,这在 Android 上是可能的,而且效果很好。为什么iOS不提供呢?无论如何感谢您的努力:)
  • 我也试过了,还是不行。由于它是 jerry-rigged,因此适当的比率不适用于 x 和 y 坐标。视图沿一个轴快速移动,沿另一轴缓慢移动。然后是相反的横向方向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多