1

iPhone ARToolkit を使用していますが、どのように機能するのか疑問に思っています。

目的地の場所、ユーザーの場所、コンパスを使用して、このツールキットがユーザーがその目的地を見ていることを知る方法を知りたいです。

この計算の背後にある数学を知るにはどうすればよいですか?

4

2 に答える 2

7

AR ToolKit が使用する数学は、基本的な三角法です。トーマスが説明している手法は使用していませんが、これはより良いアプローチだと思います(ステップ5を除く。以下を参照)

関連する手順の概要。

iPhone の GPS はデバイスの位置を提供し、見たい位置の座標を既に持っています。

最初に、2 つのポイントの緯度と経度の値の差を計算します。これらの 2 つの差の測定値は、直角三角形を作成し、現在の位置から別の特定の位置までの角度を計算できることを意味します。これは関連するコードです:

- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second {
    float longitudinalDifference = second.longitude - first.longitude;
    float latitudinalDifference = second.latitude - first.latitude;
    float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference / longitudinalDifference);
    if (longitudinalDifference > 0) return possibleAzimuth;
    else if (longitudinalDifference < 0) return possibleAzimuth + M_PI;
    else if (latitudinalDifference < 0) return M_PI;

    return 0.0f;
}

この時点で、電話からコンパス値を読み取り、デバイスが指している特定のコンパス角度 (方位角) を特定できます。コンパスの読み取り値は、カメラのビューの中心にある角度になります。AR ツールキットは、iPhone の視野が既知であるため、現在画面に表示されている角度の全範囲を計算します。

特に、ビューの左端の部分の角度が何を示しているかを計算することでこれを行います。

double leftAzimuth = centerAzimuth - VIEWPORT_WIDTH_RADIANS / 2.0;

if (leftAzimuth < 0.0) {
    leftAzimuth = 2 * M_PI + leftAzimuth;
}

そして、最も右を計算します。

double rightAzimuth = centerAzimuth + VIEWPORT_WIDTH_RADIANS / 2.0;

if (rightAzimuth > 2 * M_PI) {
    rightAzimuth = rightAzimuth - 2 * M_PI;
}

私たちは今持っています:

  1. 表示したいものの現在の位置に対する角度
  2. 現在画面に表示されている角度の範囲

これは、画面上の正しい位置にマーカーをプロットするのに十分です (一種... 以下の問題セクションを参照してください)。

また、デバイスの傾きに関連する同様の計算も行うため、空を見てもそこに都市マーカーが表示されないことを願っています。また、それを足元に向けると、理論的には地球の反対側にある都市が表示されるはずです。ただし、このツールキットでのこれらの計算には問題があります。

問題点...

デバイスの向きが完全ではありません

計算について説明した値は、デバイスを地球に対して正確な位置に保持していることを前提としています。つまり、完全に横長または縦長です。あなたのユーザーはおそらく常にそうしているとは限りません。デバイスを少し傾けると、水平線が画面上で水平ではなくなります。

地球は実は3D!

地球は三次元です。ツールキットの計算のほとんどは、それを説明しています。それが実行する計算は、デバイスを地平線に向けている場合にのみ本当に正確です.

たとえば、地球の反対側 (足の真下) にポイントをプロットしようとすると、このツールキットは非常に奇妙な動作をします。画面上の方位角範囲を計算するために使用されるアプローチは、水平線を見ている場合にのみ有効です。カメラを床に向けると、実際にすべてのコンパス ポイントを見ることができます。ただし、ツールキットは、まだ見ているだけだと考えていますcompass reading ± (width of view / 2)。その場で回転すると、マーカーが画面の端に移動し、消えて反対側に再び表示されます。あなたが期待するのは、回転してもマーカーが画面上にとどまるということです。

ソリューション

最近、AR を使ったアプリを実装しましたが、最初は AR Toolkit が面倒な作業をやってくれると思っていました。先ほど説明した問題に遭遇しましたが、これは私のアプリでは受け入れられないため、自分でロールバックする必要がありました。

Thomas のアプローチはポイント 5 までは優れた方法であり、上で説明したように、地平線に向かっている場合にのみ機能します。それ以外の何かをプロットする必要がある場合、それは崩壊します。私の場合、頭上にあるオブジェクトをプロットする必要があるため、まったく不適切です。

OpenGL ES を使用して、マーカーが実際に 3D 空間にある場所にマーカーをプロットし、コンパスに対して継続的に再調整しながら、ジャイロスコープからの読み取り値に従って OpenGL ビューポートを移動することで、これに対処しました。3D エンジンは、画面に何が表示されるかを判断するすべてのハードワークを処理します。

始めるにはこれで十分だと思います。それよりも詳細を提供できればと思いますが、多くのハッキーなコードを投稿することはできません。ただし、このアプローチは、上記の両方の問題に対処しました。ある時点でコードのその部分をオープン ソース化したいと考えていますが、現時点では非常にラフであり、問​​題のドメインに関連しています。

于 2011-10-07T13:19:44.190 に答える
3
  • 必要な情報はこれだけです。iphone-location と destination-location を使用すると、目的地の角度 (真北に対して) を計算できます。
  • 唯一欠けているのは、コンパスによって返された iPhone が現在見ている場所 (磁北 + 現在地 -> 真北) を知ることです。

編集:計算: (これは単なるアイデアです: 多くの座標変換なしでより良い解決策が存在する可能性があります)

  1. 現在地と目的地をecef座標に変換する
  2. 目的地の ecef 座標を、現在の位置を参照位置とする enu (東、北、上) ローカル座標系に変換しますこれも使えます
  3. 高さの値を無視し、enu 座標を使用して方向を取得します。atan2(deast, dnorth)
  4. コンパスはすでにiPhone が見ている角度を返します

  5. dest_angle - 10° <= compass_angle <= dest_angle + 10°
    巡回角度空間に関する場合、画面に目的地を表示します。の定数10°は単なる推測値です。有用な値を見つけるためにいくつかの値を試すか、iPhone カメラのいくつかのプロパティを分析する必要があります。

地球が楕円体ではなく球体であると仮定すると、座標変換方程式ははるかに単純になります。ポステットがある場合、ほとんどのリンクはwgs-84楕円体を想定しています。これは、gpsもafaikを行うためです)。

于 2011-10-06T11:41:21.603 に答える