2017-12-08 8 views
-1

編集: 行列を回転するときに私はまだ経度の計算に苦しんでいます。数学:モデル行列からのx0、y0、z1での経度と緯度

以下の経度公式は、惑星の北極がきれいに真っ直ぐである限り素晴らしいです。私の前方軸(ATAN2機能で使用される)がうまく回ることを可能にします。

しかし、遠くの北はまっすぐ上から落ちますが、私のforwardXとforwardZはY軸コンポーネントの影響を受けるため、ATAN2関数でエラーが発生します。

惑星の北極が水平(3時の時)で、惑星を東に回転させると(私はダウンするだろう)、ATAN2の式はforwardX

私はGoogle Earthがこれを理解していることを知っているので、方法が必要です。

どうにかして3つの軸をすべて考慮する必要があります。

私はAndroid Studio Java OpenGL 2.0で作業しています。

私は、次のコードを使用して素晴らしい作品タッチ使用して周りにスピンすることができ球体(惑星)を持つ:mAccumulatedRotaion行列が道を教えて右、上、進むベクトルが含まれてい

  // tanslate and scale the model matrix 
      Matrix.setIdentityM(SolarSystemObjects.mPlanetModelMatrix, 0); 
      Matrix.translateM(SolarSystemObjects.mPlanetModelMatrix, 0, objectX, objectY, objectZ); 
      Matrix.scaleM(SolarSystemObjects.mPlanetModelMatrix, 0, planetScale, planetScale, planetScaleZ); 

      // Set a matrix that contains the current rotation. 
      Matrix.setIdentityM(mCurrentRotation, 0); 
      Matrix.rotateM(mCurrentRotation, 0, planetRotationX, 0f, 1f, 0f); 
      Matrix.rotateM(mCurrentRotation, 0, planetRotationY, 1f, 0f, 0f); 

      // rotation to the result. 
      Matrix.multiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0); 
      System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16); 

      // Rotate the planet taking the overall rotation into account. 
      Matrix.multiplyMM(mTemporaryMatrix, 0, SolarSystemObjects.mPlanetModelMatrix, 0, mAccumulatedRotation, 0); 
      System.arraycopy(mTemporaryMatrix, 0, SolarSystemObjects.mPlanetModelMatrix, 0, 16); 

を球が回転します。だから私は北の方が自分の惑星のどちらの方か分かっている。経度と緯度

今、私はx=0f, y=0f, z=1.0f(画面のフロントとセンター)でベクターの経度と緯度を計算するために数学のヘルプが必要な

は私の惑星の北極への参照にする必要があります。 (任意の方向を指している可能性があります)

アップベクトルと右ベクトルを使用すると、これを実行する必要があるはずです。

アップ(北)がx=0.3f,y=0.6f,z=-0.45fにある場合、私のx=0f, y=0f, z=1.0f(前部および中央)ベクトルが南半球にあることがわかります。

しかし、私はどこから数学を始めるべきか分かりません。私はロング/ラトからXYZに変換するこのフォーラムの例を見つけましたが、私の問題の数学を逆にする方法はわかりません。

Iは、次のコードを使用して、2次元ベクトル間の角度を測定することにより緯度のためのソリューションを発見した:(完全動作)

float top = (northX * 0f) + (northY * 0f) + (northZ * 1f); 
float bottom = (float)(Math.sqrt((northX * northX) + (northY * northY) + (northZ * northZ)) * Math.sqrt((0f * 0f) + (0f * 0f) + (1f * 1f))); 
float latitude = 90f - (float)Math.toDegrees(Math.acos(top/bottom)); 

をしかし、これは経度のために働きません。

EDIT

: は、経度のために私は次のコードを使用しています(まだ正常に動作していない)

float longitude = (float)Math.toDegrees(Math.atan2(forwardX, forwardZ)); 

N極がまっすぐであるときに動作しますが、垂直から北極ドリフトとして失敗しました。

事前にお手数をおかけしていただきありがとうございます。

+1

[XYZへLatLon(https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates)、およびリバース:[XYZへLatLon(https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#The_application_of_Ferrari 's_solution)。フェラーリのソリューションはかなりうまくいきます。 – QBrute

答えて

0

面白いことは、緯度の計算には経度の計算よりも複雑です。後者は2つの引数の逆正接、atan2を持つ関数(これは実際にはこのタスクに専念しています)を持っています。あなただけZ(すなわちZが南北軸であると仮定して)座標、およびこの機能にX、Yフィード無視:

float longitude = (float)Math.toDegrees(Math.atan2(x,y)); 

追加する必要があるかもしれません/に削除/ 0/90/180度から0をどこにしたいか、またどの方向を増やしたいかによって異なります。

+0

私は北極がこれを動作させるためにはY軸(北)になければならないという事実を修正していますか?もしそうなら、モデル行列(私が推測する一時行列)と必要に応じて前/中央ベクトルの両方を回転させる最良の方法は何か。 –

+0

@JochumWittebroodいいえ、北極と南極の間のコンポーネントは経度にはまったく影響を与えないものですから、それは「使い捨て軸」(もちろんこの計算では)、Zのものです。他のアプローチ:経度を知るためには、北極のどこかから "トップ"から地球(そしてあなたのポイント)を見ると、あなたの方に来るコンポーネントも見えません。グリニッジが地球上にマークされていれば、それを変更せずにatan2の結果を使用するために右に回すことができます:+ Xは0子午線、+ Yは東、-Yは西です – tevemadar