1

プログラムに、ある点(x_p、y_p、z_p)を別の点(x_m、y_m、z_m)の周りで角度w_nxとw_nyだけ回転させる関数があります。新しい座標は、グローバル変数x_n、y_n、およびz_nに格納されます。y軸を中心とした回転(y値が損なわれないようにw_nxの値を変更する)は正しく機能していますが、x軸またはz軸を中心に回転するとすぐに(w_nyの値を変更します)座標はもう正確ではありません。私は自分のせいであると思う行にコメントしましたが、そのコードの何が問題なのか理解できません。

誰か助けてもらえますか?

void rotate(float x_m, float y_m, float z_m, float x_p, float y_p, float z_p, float w_nx ,float w_ny)
    {
        float z_b = z_p - z_m;
        float x_b = x_p - x_m;
        float y_b = y_p - y_m;
        float length_ = sqrt((z_b*z_b)+(x_b*x_b)+(y_b*y_b));
        float w_bx = asin(z_b/sqrt((x_b*x_b)+(z_b*z_b))) + w_nx;
        float w_by = asin(x_b/sqrt((x_b*x_b)+(y_b*y_b))) + w_ny; //<- there must be that fault
        x_n = cos(w_bx)*sin(w_by)*length_+x_m;
        z_n = sin(w_bx)*sin(w_by)*length_+z_m;
        y_n = cos(w_by)*length_+y_m;
    }
4

4 に答える 4

5

コードのほとんどの機能:

  • 差分ベクトルを計算する
  • ベクトルを球座標に変換する
  • 傾斜角と方位角に w_nx と wn_y を追加します (用語についてはリンクを参照してください)。
  • 修正された球座標をデカルト座標に戻す

2 つの問題があります。

  • 変換が正しくありません。計算は 2 つの傾斜ベクトル (1 つは x 軸に沿ったもの、もう 1 つは y 軸に沿ったもの) に対するものです。
  • 計算が正しかったとしても、球座標での変換は 2 つの軸を中心とした回転と同じではありません

したがって、この場合、行列とベクトルの計算を使用すると役立ちます。

b = p - m
b = RotationMatrixAroundX(wn_x) * b
b = RotationMatrixAroundY(wn_y) * b
n = m + b

基本的な回転行列.

于 2012-11-07T20:54:21.087 に答える
4

ベクトル演算を使用してみてください。最初に x に沿って、次に y に沿って、回転する順序を決定します。

z に沿って回転すると、[z' = z]

x' = x*cos a - y*sin a;
y' = x*sin a + y*cos a;  

y 軸についても同じことが繰り返されます: [y'' = y']

x'' = x'*cos b - z' * sin b;
z'' = x'*sin b + z' * cos b;  

再び x 軸に沿って回転: [x''' = x'']

y''' = y'' * cos c - z'' * sin c
z''' = y'' * sin c + z'' * cos c

そして最後に、ある特定の「ポイント」を中心に回転する問題:

最初に座標からポイントを減算し、次に回転を適用して、最後にポイントを結果に戻します。

私が見る限り、問題は「ジンバルロック」に近いものです。角度 w_ny は、固定の xyz 座標系に対して測定することはできませんが、角度 w_nx を適用して回転させた座標系に対して測定することはできません。

kakTuZ が観察したように、コードはポイントを球座標に変換します。それには本質的に何の問題もありません。経度と緯度があれば、地球上のすべての場所に到達できます。そして、地球の赤道面を太陽の周りの軌道に対して傾けることを気にしなければ、私には問題ありません。

最初の w_ny に沿って次の基準軸を回転させない結果、赤道で互いに 1 km 離れている 2 つの点が、極で互いに接近し、緯度 90 度で接触します。明らかな目的は、回転する場所でそれらを 1 km 離すことです。

于 2012-11-07T18:27:16.993 に答える
0

ポイントだけでなく座標系を変換する場合は、3つの角度が必要です。しかし、あなたは正しいです-ポイントを変換するには、2つの角度で十分です。詳細については、ウィキペディアにお問い合わせください...

しかし、openglを使用する場合は、実際にはのようなopengl関数を使用する必要がありますglRotatef。これらの関数は、関数としてのCPUではなくGPUで計算されます。ドキュメントはこちらです。

于 2012-11-07T19:00:38.307 に答える
0

他の多くの人が言ったように、glRotatef を使用してレンダリング用に回転させる必要があります。衝突処理では、レンダリングの時点でスタックの一番上にある OpenGL ModelView マトリックスでその位置ベクトルを乗算することにより、そのワールド空間位置を取得できます。その行列を glGetFloatv で取得し、独自のベクトル行列乗算関数で乗算するか、オンラインで簡単に取得できる多くの関数のいずれかを使用します。

しかし、それは苦痛でしょう!代わりに、GL フィードバック バッファーの使用を検討してください。このバッファは、実際にプリミティブを描画する代わりに、プリミティブが描画されたはずのポイントを単純に保存し、そこからアクセスできます。
これは良い出発点です。

于 2012-11-07T22:05:48.810 に答える