0

ここに点P(x、y、z、1)があります。次に、既知の天使とベクトルを中心にPを回転させてP1(x1、y1、z1,1)をポイントします。そして、P1の座標に従って、P1を点P2(0,0、z1,1)に変換できます。ここで、PをP2に直接変換できる行列を1つだけ取得したいので、私のコードは次のとおりです。

GLfloat P[4] ={5,-0.6,3.8,1};
GLfloat m[16];  //This is the rotation matrix to calculate P1 from P
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRotatef(theta, v1,v2,v3);//theta and (v1,v2,v3) is constant
glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPopMatrix();

//calculate P1 from P and matrix m
GLfloat P1;
P1[0] = P[0]*m[0]+P[1]*m[4]+P[2]*m[8]+m[12];
P1[1] = P[0]*m[1]+P[1]*m[5]+P[2]*m[9]+m[13];
P1[2] = P[0]*m[2]+P[1]*m[6]+P[2]*m[10]+m[14];
P1[3] = P[0]*m[3]+P[1]*m[7]+P[2]*m[11]+m[15];
//after calculation P1 = {0.15,-3.51,-5.24,1}

GLfloat m1[16]; //P multiply m1 can get P2 directly
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRotatef(theta, v1,v2,v3);//theta and (v1,v2,v3) is constant as above
glTranslatef(-P1[0], -P1[1], 0);// after rotation we get P1, then translation to P2  
glGetFloatv(GL_MODELVIEW_MATRIX, m1);
glPopMatrix();

//calculate P2 from P and matrix m1
GLfloat P2[4];
P2[0] = P[0]*m1[0]+P[1]*m1[4]+P[2]*m1[8]+m1[12];
P2[1] = P[0]*m1[1]+P[1]*m1[5]+P[2]*m1[9]+m1[13];
P2[2] = P[0]*m1[2]+P[1]*m1[6]+P[2]*m1[10]+m1[14];
P2[3] = P[0]*m1[3]+P[1]*m1[7]+P[2]*m1[11]+m1[15];
//after this calculation, I expect P2 should be (0,0,-5.24) that is (0,0,p1[2])
//however, the real result is not my expectation! Where I do wrong???

実際、私はこの問題を分析しました。行列の乗算の順序がおかしいことがわかりました。glRotatef(theta、v1、v2、v3)を実行した後、行列mを取得します。それで大丈夫です。mは

m [0] m [1] m [2] 0

m [4] m [5] m [6] 0

m [8] m [9] m [10] 0

0 0 0 1

そして、glTranslatef(-P1 [0]、-P1 [1]、0)だけを実行すると、変換行列m'が得られます。m'は

1 0 0 0

0 1 0 0

0 0 0 1

-P1 [0] -P1 [1] 0 1

したがって、glRotatef(theta、v1、v2、v3)とglTranslatef(-P1 [0]、-P1 [1]、0)を実行した後、m1 = m * m'、つまり

m [0] m [1] m [2] 0

m [4] m [5] m [6] 0

m [8] m [9] m [10] 0

-P1 [0] -P2 [0] 0 1

ただし、実際のプログラムでは、m1 = m'* mであるため、P2は期待した結果ではありません。

最初に平行移動を実行してから、正しい結果を得ることができる回転を実行することは知っていますが、なぜ最初に回転を実行できないのですか?

4

1 に答える 1

2

回転と平行移動は転流できません。(一般に行列の乗算は可換ではありませんが、すべての平行移動、すべての2D回転、すべてのスケーリング、均一なスケーリングと混合された1つの回転など、一部の特殊なケースでは、アクション/行列は可換です)。

最初に回転すると、回転した座標の方向に平行移動します。

例として、(1、0)で移動し、次に90度回転すると、(1、0)で原点が得られます(単位行列から開始すると仮定)。最初に90度回転するのとは対照的に、原点は(0、1)になります。

数学的な面では、これは座標変換であるため、新しい変換は現在の座標変換行列に乗算されたままになります。たとえば、Tが新しい変換アクションの行列である場合、Cは現在の変換行列であり、変換後、現在の変換行列はTCになります。

于 2012-05-30T10:50:34.907 に答える