1
float carX   = 0.0;
float carY   = 0.0;
float carSpeed = 1.0;
float direction = 0.0;
bool exhaust;



void reshape(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 10.0, 0, 10.0, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}

void keys(int key, int x, int y){


if(key == GLUT_KEY_UP){
    carY = carY + carSpeed;
    direction = 0.0;
    glutPostRedisplay();
}
if(key == GLUT_KEY_DOWN){
    carY = carY - carSpeed;
    direction = 90.0;
    glutPostRedisplay();

}

if(key == GLUT_KEY_LEFT){
    carX = carX - carSpeed;
    direction = -90.0;
    glutPostRedisplay();
}

if(key == GLUT_KEY_RIGHT){
    carX = carX + carSpeed;
    direction = 180.0;
    glutPostRedisplay();
}}

void renderScene(void){
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawPlayground();
glPushMatrix();
glRotatef(direction, 0.0, 0.0, 1.0);
glTranslatef(carX, carY,0.0);
drawcar();
glPopMatrix();
glFlush();}

int main(int argc, char** argv){
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (400, 400);
   glutInitWindowPosition (100, 100);
   glutCreateWindow("courseWork_2DGame");
   reshape();
   glutDisplayFunc(renderScene);
   glutSpecialFunc(keys);
   glutMainLoop();
   return 0;}

これは私のopenGLコードです。車が動き回る遊び場を描きました。車は移動しますが、矢印が移動します。方向は、押された矢印キーに応じた車の回転です。ただし、キーを押すと車はうまく移動しますが、回転が正しくないので、中心を回転させず、別の位置を回転させていると思います。

4

1 に答える 1

2

これについて非常に詳細に説明した投稿を覚えていますhere。この男は、マトリックス階層全体を説明するという驚くべき仕事をしました。


オブジェクトをその中心を中心に回転させたい場合は、最初にオブジェクトを原点に移動してから、回転させて元に戻す必要があります。変換行列はベクトルに右から左へ影響するため、これらの手順を逆の順序でコーディングする必要があります。

私は OpenGL ルーチンを暗記していないので、いくつかの疑似コードを次に示します。

PushMatrix();
LoadIdentity();  // Start with a fresh matrix
Translate();     // Move your object to its final destination
Rotate();        // Apply rotations
Draw();          // Draw your object using coordinates relative to the object center
PopMatrix();

これらのマトリックスが適用されます。

v_t = (I * T * R) * v = (I * (T * (R * v)))

したがって、順序は次のとおりです。回転、平行移動。

編集:上記の方程式の説明。

変換の回転、スケール、および平行移動は、モデル ビュー マトリックスに影響します。モデルのすべての 3D ポイント (ベクトル) にこのマトリックスを掛けて 3D 空間の最終ポイントを取得し、次に射影マトリックスを掛けて 2D ポイント (2D 画面上) を受け取ります。

射影を無視すると、モデルビューマトリックスによって変換されたポイントは次のとおりです。

v_t = MV * v

model-view-matrix MV を乗じた元のポイント v を意味します。

上記のコードでは、恒等行列 I、平行移動 T、および回転 R によって MV を構築しました。

MV = I * T * R

すべてをまとめると、点 v が最初に回転 R の影響を受け、次に平行移動 T の影響を受けることがわかります。これにより、点が平行移動される前に回転されます。

v_t = MV * v = (I * T * R) * v = T * (R * v)

Translate() の前に Rotate() を呼び出すと、次のようになります。

v_t = (I * R * T) * v = R * (T * v)

これは悪いことです: 3D のあるポイントに変換され、次に原点を中心に回転し、モデルに奇妙な歪みが生じます。

于 2012-11-14T04:21:22.673 に答える