1

私は現在、拡張現実に取り組んでいます。そのために、ジャイロスコープとコアモーションを使用したいと思います。私はApplepARkのサンプルコードを研究しましたが、一見明確ではなかったため、ドキュメントを読むために費やした数学のほとんどを理解しています。ランドスケープモードで動作させるまでは、すべて問題ありません。

ここではすべての理論を説明することはしませんが、長すぎるでしょう。しかし、それを経験した人にとって、私の問題は、姿勢の回転行列を使用して、この回転を座標に適用することです。さて、ここまでは問題ありませんが、CoreMotionはランドスケープモードに適応していないようです。私はこのテーマについて同様の質問を見ましたが、誰も解決策を持っていないようです。

だから私は自分で作ってみました、これが私が思うことです:

デバイスを横向きに回転させるたびに、+-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

昨日、これ (Apple の pARk サンプル) をランドスケープ (右) に適応させることができたので、加えられた変更を共有したいと思います。正常に動作しているように見えますが、間違いがあれば指摘してください。これは横向きの右のみをサポートしますが、おそらく左にも簡単に適応できます。

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
于 2013-01-04T19:31:01.813 に答える