OpenGL对象不会转换为旋转轴

时间:2016-03-14 06:54:50

标签: c++ opengl

我在2d轮换中遇到问题。使用opengl绘图原语GL_LINES绘制三角形。

Image Traingle

场景是我希望使用ER键旋转此三角形,并按up down left将此三角形沿其旋转轴平移right箭头键。

Image 2

但现在三角形是旋转的,但不会沿着它的旋转轴平移。例如,简单来说,当用户按向上箭头键时我将物体旋转90度,它不会翻转那个三角形在90度的角度下,它只是简单地上下翻译那个物体我就是坚持这个 这是我的代码:

#include<iostream>
#include <cstdlib>
#include<GL\freeglut.h> 

using namespace std;    
float posX = 0.0f, posY = 0.0f, move_unit = 0.01f, angle = 0.0f;    
void init(void) {

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, -1.0);    
}

void drawFigure() {
    //LINES Make traingle
    glColor3f(1.0f, 1.0f, 0.0f);    
    glBegin(GL_LINES);    
    glVertex2f(0.1f, 0.0f);
    glVertex2f(-0.1f, 0.0f);
    glVertex2f(0.0f, 0.1f);
    glVertex2f(-0.1f, 0.0f);
    glVertex2f(0.0f, 0.1f);
    glVertex2f(0.1f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2f(0.0f, 0.1f);
    glVertex2f(0.0f, 0.0f);    
    glEnd();    
}

void SpecialKeys(int key, int xpos, int ypos) {

    if (key == GLUT_KEY_UP) {    
        if (posY < 0.95f) {
            posY += move_unit;
        }
    }
    else if (key == GLUT_KEY_DOWN) {
        if (posY > -1.0f) {
            posY -= move_unit;
        }
    }
    else if (key == GLUT_KEY_RIGHT) {
        if (posX < 0.95f) {
            posX += move_unit;
        }

    }
    else if (key == GLUT_KEY_LEFT) {
        if (posX > -0.95f) {
            posX = posX - move_unit;
        }
    }
    glutPostRedisplay();
}


void KeysFun(unsigned char key, int xpos, int ypos) {
    if (key == 'e' || key == 'E') {
        angle++;
    }
    else if (key == 'r' || key == 'R') {
        angle--;
    }

    glutPostRedisplay();    
}


void display() {    
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glPushMatrix();
    glTranslatef(posX, posY, 0.0f); 
    glRotatef(angle, 0.0f, 0.0f, 1.0f);   
    drawFigure();    
    glPopMatrix();    

    glFlush();    
}

int main(int argc, char**argv) {
    glutInit(&argc, argv);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(450, 50);
    glutCreateWindow("C");
    init();
    glutDisplayFunc(display);
    glutSpecialFunc(&SpecialKeys);
    glutKeyboardFunc(&KeysFun);
    glutMainLoop();

    return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:-1)

好吧,我在阅读时误解了你的代码,但我将它复制到了我的电脑上。

正如我在评论中所说,变换的常见顺序是你正在做的TRS(翻译后跟旋转然后是缩放)。这样,您的对象将首先围绕原点缩放,然后围绕自身旋转,然后才转换为另一个点。

我从你的问题中理解的是你希望物体围绕一个点旋转,然后不是在屏幕上移动参考(向上总是向上等),你希望它相对移动到它的新前向矢量,或者旋转轴。然后你必须在>之前放置旋转。

rotate( angle, 0.0f, 0.0f, 1.0f );
translate( posX, posY, 0.0f );

现在,对象应围绕原点旋转,并相对于当前旋转轴移动。此外,如果要围绕另一个点旋转,还可以在旋转之前添加另一个平移。

translate( centerX, centerY, 0.0f );
rotate( angle, 0.0f, 0.0f, 1.0f );
translate( posX, posY, 0.0f );

编辑: 这读作,将对象转换为点(posX, posY),围绕中心点(0,0,1)在轴(centerX, centerY)中旋转对象。

EDIT2: 如果centerX和centerY是(0,0),即原点,它的外观如下。三角形以(0,0)为中心开始。

Triangle motion example

EDIT3:

从评论中,您需要更改输入。使用原始问题中的变换,即。轮换前的翻译。

// Let's assume we have a vector2 class that stores two floats
vector2 forward;
forward.x = sin( -_angle * DEG_TO_RADIANS );
forward.y = cos( -_angle * DEG_TO_RADIANS );

vector2 right;
right.x = forward.y;
right.y = -forward.x;

// Move one tenth of the length of the forward vector
float velocity = 0.1f;

if ( key == GLUT_KEY_UP ) {
    pos += forward * velocity;
}
else if ( key == GLUT_KEY_DOWN ) {
    pos -= forward * velocity;
}
else if ( key == GLUT_KEY_RIGHT ) {
    pos += right * velocity;
}
else if ( key == GLUT_KEY_UP ) {
    pos -= right * velocity;
}

当然,请根据需要更改值。不要忘记三角函数采用弧度值。此外,由于默认情况下您的对象朝上,因此使用角度0 direction (0,1)对应于传统数学中的角度90,因此您必须相应地将参数调整为三角函数。

Triangle moving like a player character