経度と緯度があり、これを四元数に変換したいのですが、どうすればこれができるのでしょうか? これを使用したいのは、球体に地球を投影するアプリがあり、ある場所から別の場所に回転したいからです。
一番!
経度と緯度があり、これを四元数に変換したいのですが、どうすればこれができるのでしょうか? これを使用したいのは、球体に地球を投影するアプリがあり、ある場所から別の場所に回転したいからです。
一番!
この numpy implementationと同様に、行列やベクトルを使用せずにこれを行う方法があります。経度/緯度は、一緒に構成された 2 つのクォータニオン回転と考えることができます。
Z アップ右手座標系で作業してみましょう。経度をφ、緯度をθとし、両者で表される点を(φ,θ)とします。視覚化のために、赤い軸は X に、緑は Y に、青は Z に対応します。
赤で (0, 0) から緑で( a , b ) への回転を表すクォータニオンを見つけたいとします。
この回転は、次のように、最初に縦方向の回転、次に横方向の回転の組み合わせとして表すことができます。
まず、 Z 軸に沿ってaだけ回転し、X 軸と Y 軸を変換します。次に、新しいローカル Y 軸に沿ってbだけ回転しました。したがって、この回転の 2 つのセットの軸/角度情報がわかります。
幸いなことに、軸/角度からクォータニオンへの変換は既に知られています。角度 α と軸ベクトル ω を指定すると、結果の四元数は次のようになります。
(cos(α/2), ω.x*sin(α/2), ω.y*sin(α/2), ω.z*sin(α/2))
したがって、最初の回転はワールド (0, 0, 1) 軸に沿ったa度の回転で表され、次のようになります。
q1 = (cos(a/2), 0, 0, sin(a/2))
2 番目の回転は、変換/ローカル (0, 1, 0) 軸に沿ったb度の回転で表され、次のようになります。
q2 = (cos(b/2), 0, sin(b/2), 0)
これら 2 つの四元数を乗算して、(0, 0) から ( a , b ) へのこの合成回転を表す単一の四元数を得ることができます。クォータニオン乗算の式は少し長くなりますが、ここで見つけることができます。結果:
q2*q1 = (cos(a/2)cos(b/2), -sin(a/2)sin(b/2), cos(a/2)sin(b/2), sin(a/2)cos(b/2))
大した意味はありませんが、この式が前述の numpy の実装と同じであることは確認できます。
JCooper は、この場合、X 軸に沿って 1 つの自由度がまだ残っているという素晴らしい点に言及しました。θ が ±90 度以内であれば、Z 軸は常に上を向いていると想像できます。これは、X 軸の回転を制限する効果があり、希望どおりになることを願っています。
お役に立てれば!
編集: これは本質的に 2 つのオイラー角を扱うことと同じであることに注意してください。したがって、この変換を逆にするには、回転順序が同じであれば、任意のクォータニオンからオイラー角への変換を使用できます。
ブースト C++ ライブラリがそれをどのように実装しているかを調べることができるかもしれません。(またはおそらくそれを使用しても)http://www.boost.org/doc/libs/1_46_0/libs/math/doc/quaternion/html/boost_quaternions/quaternions/create.html
経度と緯度は、球面座標の方位角 (theta - [0, 2*PI]) と傾斜角 (rho? [0,PI]) にかなり似ています (もちろん、表面の場合は半径 r=1)。ブーストには、私が投稿したリンクで球状から四元数までの機能があります。
四元数を説明するには、緯度と経度だけでは不十分です。緯度と経度は、3D 球面上の点を表すことができます。それが、法線が画面を直接指しているポイントであるとしましょう。あなたにはまだ自由度が残っています。球体は、lat-lon で指定された点の法線ベクトルの周りを回転できます。球の向きを表すクォータニオンが必要な場合は、回転を完全に指定する必要があります。
では、球の北極を上向きに保ちたいとしましょう。北極がオブジェクトの+z軸に位置合わせされ、画面上の「上」がワールドの+y軸に位置合わせされている場合、球面の点Rが直接外を向くように球体を回転させたい場合画面(コメントで言及したように、緯度経度からユークリッドを使用してRが見つかった場所)で、次のように回転行列を作成します。
オブジェクトのRをワールドの+z (OpenGL のようなビュー座標系を想定) に揃え、オブジェクトの+zをワールドの+yに揃える(できるだけ近い) ようにします。3 番目の軸が必要です。したがって、 Rを正規化して、 P = crossP([0 0 1]^T,R)を見つけます。Pを正規化し、2 番目の軸に直交性を適用します: Q = crossP(R,P)。最後に、Qを正規化します。これで、それぞれワールドのx、y、zに揃えたい3 つの直交ベクトルP、Q、Rができました。
P、Q、およびRは列ベクトルであると想定しています。したがって、変換行列を作成するには、これらをくっつけるだけです: M = [PQR] . ここで、 Mはワールド座標の点をオブジェクト座標に変換する行列です。反対方向に進むには、Mの逆数を見つけます。さいわい、行列の列が正規直交行列の場合、逆行列は転置と同じです。したがって、次のようになります。
[ P^T ]
M^-1 = M^T = [ Q^T ]
[ R^T ]
そこから、必要に応じて、マトリックスからクォータニオンへの変換を使用してクォータニオンを見つけることができます。そして、slerp または選択した方法を使用して、クォータニオン間を補間できます。