OpenGL, вращение вокруг точки не работает до сих пор вокруг начала координат - PullRequest
1 голос
/ 21 марта 2012

Я сделал (перевести, повернуть, перевести) вещь, но она все еще вращается вокруг начала координат. Все, что я сделал, когда вы нажмете клавишу r, начнется трюк, который (переводить, вращать, переводить). в результате он все еще вращается вокруг начала координат

#include <gl/glut.h> 

void OnKeyPress(unsigned char key, int x, int y) 
{ 
    if (key == 27)  
        exit(0); 
    switch(key) 
    { 
    case 'r': 
    case 'R': 
        // trick start here *********************
        glTranslatef(-60,-20,0);
        glRotatef(10, 0, 0, 1);
        glTranslatef(60, 20, 0);
        glutPostRedisplay();
        break; 
    };
} 

void OnDisplay()  
{  
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(0.0f,0.5f,1.0f); 

    glBegin(GL_TRIANGLES); 
    glVertex2f(20, 20); 
    glVertex2f(60, 20);
    glVertex2f(20, 100);
    glEnd(); 
    glFlush();  
} 

int  main( int  argc, char *argv[]) 
{
    glutInit(&argc, argv);       
    glutInitDisplayMode(GLUT_RGBA);   
    glutInitWindowPosition(100, 100);  
    glutInitWindowSize(800, 600); 
    glutCreateWindow("OpenGL Lab1" ); 
    glutDisplayFunc(OnDisplay);
    glutKeyboardFunc(OnKeyPress); 

    glClearColor(1.0, 1.0, 1.0, 0.0);    
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity(); 
    gluOrtho2D(-100, 100,  -100, 100);  

    glutMainLoop();  

    return 0; 
}

Ответы [ 2 ]

4 голосов
/ 21 марта 2012

Вам необходимо изменить порядок вызовов glTranslate, поскольку последнее выполненное преобразование является первым, примененным к вершине.Видите, каждое преобразование - это матрица, на которую умножается ваша текущая матрица.Результирующая матрица затем умножается на вершину, чтобы определить ее конечную позицию.

Итак, если у вас есть:

 glTranslatef(-60,-20,0); (T1)
 glRotatef(10, 0, 0, 1);  (R)
 glTranslatef(60, 20, 0); (T2)

, а также имеется старая матрица Мо, сохраненная из предыдущего кадра,у вас будет:

 M = (((Mo * T1) * R) * T2)

, в конце эта M умножается на каждую вершину Vo, чтобы определить ее конечную позицию:

 V = M * Vo

Умножения матриц некоммутативны, но ониявляются ассоциативными, поэтому порядок скобок не имеет значения, и все эти преобразования математически эквивалентны:

 V = Mo * T1 * R * (T2 * Vo)

Обратите внимание, что (T2 * Vo) - вершина, преобразованная с помощью T2 (ваш последний перевод).Если мы назовем его V1, то получим:

 V = Mo * T1 * (R * V1)

. Видим, что V1, ваша исходная вершина, преобразованная с помощью T2, теперь, в свою очередь, преобразуется вращением R в (R * V1), в результате чего получается другая вершина., теперь переведено, а затем повернуто.Продолжайте решать выражение справа налево, и все преобразования будут применены к вершине в обратном порядке в том месте, где они были «вызваны» в коде OpenGL.

Я полагаю, вы знаете, почему вам нужноtranslate-rotate-untranslate для вращения вокруг желаемой точки, но вы ошиблись, когда сказали, что «вещь» вращается вокруг источника в вашем коде.На самом деле, если вы обратите внимание, вы заметите, что он вращался вокруг точки (-60, -20).

Наконец, вы не используете матрицу вида модели, а выполняете все преобразования, используяматрица перспективы (которая, кстати, работает, поскольку вы не сбрасываете ее каждый кадр, как это делает большинство приложений).Вы не должны делать это, а вместо этого использовать GL_MODELVIEW для такого рода преобразований.Попробуйте завершить функцию инициализации с помощью:

...
  Set_Transformations();
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glutMainLoop();
}
1 голос
/ 21 марта 2012

Переверните его (+, rot, -) вместо (-, rot, +):

#include <gl/glut.h> 

int angle = 0;
void OnKeyPress(unsigned char key, int x, int y) 
{ 
    if (key == 27)  
        exit(0); 
    switch(key) 
    { 
    case 'r': 
    case 'R': 
        angle += 10;
        glutPostRedisplay();
        break; 
    };
} 

void OnDisplay()  
{  
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(0.0f,0.5f,1.0f); 

    glClearColor(1.0, 1.0, 1.0, 0.0);    
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity(); 
    gluOrtho2D(-100, 100, -100, 100);  

    glMatrixMode(GL_MODELVIEW);  
    glLoadIdentity(); 

    // trick start here *********************
    glTranslatef(60, 20, 0);
    glRotatef( angle, 0, 0, 1);
    glTranslatef(-60,-20,0);

    glBegin(GL_TRIANGLES); 
    glColor3ub(0,0,255);
    glVertex2f(20, 20); 
    glColor3ub(255,0,0);
    glVertex2f(60, 20);
    glColor3ub(0,0,255);
    glVertex2f(20, 100);
    glEnd(); 

    glFlush();  
} 

int  main( int  argc, char *argv[]) 
{
    glutInit(&argc, argv);       
    glutInitDisplayMode(GLUT_RGBA);   
    glutInitWindowPosition(100, 100);  
    glutInitWindowSize(800, 600); 
    glutCreateWindow("OpenGL Lab1" ); 
    glutDisplayFunc(OnDisplay);
    glutKeyboardFunc(OnKeyPress); 

    glutMainLoop();  

    return 0; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...