1

シナリオは次のとおりです。

オブジェクトは次のように記述されます:

  • 位置
  • 規模
  • 回転

最初に OpenGL からモデル ビュー (カメラ) を適用し、次に次のマトリックスを使用して移動と回転を適用します。

    private Matrix4d AnglesToMatrix(Vector3d angles)
    {
        Vector3d left = Vector3d.UnitX;
        Vector3d up = Vector3d.UnitY;
        Vector3d forward = Vector3d.UnitZ;

        AnglesToAxes(angles, ref left, ref up, ref forward);

        return new Matrix4d(
            new Vector4d(left.X, up.X, forward.X, 0),
            new Vector4d(left.Y, up.Y, forward.Y, 0),
            new Vector4d(left.Z, up.Z, forward.Z, 0),
            new Vector4d(0, 0, 0, 1));
    }

    private void AnglesToAxes(Vector3d angles, ref Vector3d left, ref Vector3d up, ref Vector3d forward)
    {
        const double DEG2RAD = 0.0174532925;
        double sx, sy, sz, cx, cy, cz, theta;

        // rotation angle about X-axis (pitch)
        theta = angles.X * DEG2RAD;
        sx = Math.Sin(theta);
        cx = Math.Cos(theta);

        // rotation angle about Y-axis (yaw)
        theta = angles.Y * DEG2RAD;
        sy = Math.Sin(theta);
        cy = Math.Cos(theta);

        // rotation angle about Z-axis (roll)
        theta = angles.Z * DEG2RAD;
        sz = Math.Sin(theta);
        cz = Math.Cos(theta);

        // determine left axis
        left.X = cy * cz;
        left.Y = sx * sy * cz + cx * sz;
        left.Z = -cx * sy * cz + sx * sz;

        // determine up axis
        up.X = -cy * sz;
        up.Y = -sx * sy * sz + cx * cz;
        up.Z = cx * sy * sz + sx * cz;

        // determine forward axis
        forward.X = sy;
        forward.Y = -sx * cy;
        forward.Z = cx * cy;
    }

で、最後にスケールを適用します。グローバル軸に基づく回転を除いて、すべてが見栄えがします。

ローカル軸を使用してオブジェクトを回転するには?

質問を正確にするため。オブジェクトを Y 軸で 45 度回転すると、X 軸と Z 軸が回転し、別の回転を適用して新しい軸を使用します。

マイナスの形での罰を避けるために... 3D空間での回転に関連するすべての主題を読みましたが、解決策はありませんでした。上記のコードは、さまざまな試行を適用した結果ですが、次のような結果が得られます。

        GL.Rotate(Rotation.X, Vector3d.UnitX);
        GL.Rotate(Rotation.Y, Vector3d.UnitY);
        GL.Rotate(Rotation.Z, Vector3d.UnitZ);

編集: 結局のところ 、私たちのデザイナーは 3D でのオブジェクトの回転について悪い期待を持っていましたが、それでも問題は存在します。使用する言語に関しては、これを C# で記述しますが、C または C++ で解決策を教えていただければ、私が対応します :D

現在使用しています (順序を構成できます):

GL.Rotate(Rotation.X, Vector3d.UnitX);
GL.Rotate(Rotation.Y, Vector3d.UnitY);
GL.Rotate(Rotation.Z, Vector3d.UnitZ);

しかし、これはワールド軸を中心にオブジェクトを回転させます。XYZ 軸の回転があると仮定して、ローカル オブジェクト軸を次のように使用します。

GL.Rotate(Rotation.X, Vector3d.UnitX);
GL.Rotate(Rotation.Y, newYaxis);
GL.Rotate(Rotation.Z, newZaxis);

または、YXZ 軸の回転があると仮定します

GL.Rotate(Rotation.Y, Vector3d.UnitY);
GL.Rotate(Rotation.X, newXaxis);
GL.Rotate(Rotation.Z, newZaxis);

最も効率的な方法は、回転行列を事前に計算することですが、回転後に新しい軸を決定する方法はまだ疑問に思っています。(三角法の本を再訪する必要があるようです)。誰かが回転行列を非常に高速に計算するソリューションを持っていれば、私は感謝しています。今のところ、各パスで三角法の計算を使用してみます。

4

2 に答える 2

0

私はopentkはあまり得意ではありませんが、Cスタイルのopenglの場合、これは乗算前と乗算後の違いです。前乗算はワールド座標空間で発生し、後乗算はローカル座標空間で発生します。http://www.opengl.org/archives/resources/faq/technical/transformations.htmセクション 9.070を参照してください。

行列の乗算を実行する実際の行列へのハンドルを取得できる場合、これは機能するはずです。

于 2012-08-07T22:46:01.577 に答える
0

ここでどのような状況を想像しているのか正確に言えますか?

あなたの要求には意味がないと思います。どのような回転でも、別の操作の前 (グローバル軸) または別の操作の後に (ローカル軸) 適用できます。したがって、3 つの回転を適用する場合は、1 つの軸の回転を最初に、別の軸の回転を 2 番目に、別の軸の回転を 3 番目にする必要があります。

3 つの回転を適用したいと言っていますが、各回転を他の 2 つの回転の前に発生させたいと言っています。彼ら全員が最初になることはできません。

どのような種類の回転を実現しようとしているのかについての説明 (画像が望ましい) を追加していただければ、この誤解を解くことができるかもしれませんが、現在あなたが求めていることは、物理的な現実では意味がありません。

于 2012-08-07T22:47:25.457 に答える