1

モデル ビュー マトリックスからスケール マトリックスを抽出するにはどうすればよいですか? 現在、各列の長さを取っていますが、スケールが負の場合は失敗します。ここに私のコードがあります:

  float xs =
            matrix[0][0] * matrix[0][1] * matrix[0][2] * matrix[0][3] < 0 ?
                    -1 : 1;
    float ys =
            matrix[1][0] * matrix[1][1] * matrix[1][2] * matrix[1][3] < 0 ?
                    -1 : 1;
    float zs =
            matrix[2][0] * matrix[2][1] * matrix[2][2] * matrix[2][3] < 0 ?
                    -1 : 1;


    glm::vec3 new_scale;
    new_scale.x =  xs* glm::sqrt(
                    matrix[0][0] * matrix[0][0] + matrix[0][1] * matrix[0][1]
                            + matrix[0][2] * matrix[0][2]);
    new_scale.y =  ys* glm::sqrt(
                    matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1]
                            + matrix[1][2] * matrix[1][2]);
    new_scale.z = zs* glm::sqrt(
                    matrix[2][0] * matrix[2][0] + matrix[2][1] * matrix[2][1]
                            + matrix[2][2] * matrix[2][2]);

例えば:

float []mat={0.032254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, -0.0052254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.4332254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f};
4

1 に答える 1

1

同次変換行列を参照してください。スケールを抽出する方法は問題ありません。じゃあサインは?変換に回転が含まれている場合、現在のアプローチは機能しません...

もう 1 つの問題は、1 つの軸を否定すると、他の軸を否定して位置に合わせて回転させても同じ結果が得られるため、どのスケールが否定され、どの尺度が否定されていないかがわからないことです。2 つの軸を無効にすると、回転が異なる元の行列が得られます。

あなたができる最善のことは、マトリックスが1つまたは3つの軸を反転させているかどうかを検出することです:

  1. 元の歪みのない行列の符号表を作成する

    たとえば、単位行列ですが、開始点が異なる場合はそれを使用します

    sz0=dot(cross(X0,Y0),Z0);
    sy0=dot(cross(Z0,X0),Y0);
    sx0=dot(cross(Y0,Z0),X0);
    

    X0,Y0,Z0開始点マトリックスから抽出された軸ベクトルはどこにありますか

  2. 現在の行列の符号を計算します

    sz1=dot(cross(X1,Y1),Z1);
    sy1=dot(cross(Z1,X1),Y1);
    sx1=dot(cross(Y1,Z1),X1);
    

    X1,Y1,Z1実際の行列から抽出された軸ベクトルはどこにありますか

  3. 符号を比較し、どの軸のスケールが負であるかを推測します

    (sx0*sx1<0)||(sy0*sy1<0)||(sz0*sz1<0)3 つの軸の 1 つまたはすべてが否定されているが、どれがどれかわからない場合... また、3 つの符号比較はすべて同じ結果になるはずです。

[編集1] 説明

  • X=(matrix[0][0],matrix[0][1],matrix[0][2])
  • dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.zベクトルのスカラー倍数 (内積)
  • c=cross(a,b) ... c.x=a.y*b.z+a.z*b.y c.y=a.z*b.x+a.x*b.z c.z=a.x*b.y+a.y*b.xはベクトル乗算 (外積)

したがって、2 つのベクトルのクロスを計算すると、両方のオペランドに垂直なベクトルが得られます。行列の軸ベクトルは、2 つの軸を乗算することによって垂直になる必要があるため、3 番目の軸が得られます。内積は、元の軸と計算された 3 番目の軸が同じ方向にあるかどうかを比較するだけです...この方法は回転に対して不変です

于 2015-11-05T08:22:05.433 に答える