OpenGL对象无法平移到旋转轴 [英] OpenGL object doesn't translate to rotation axis

查看:99
本文介绍了OpenGL对象无法平移到旋转轴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在2D旋转中遇到问题.通过使用opengl绘制图元GL_LINES绘制三角形.

I'm facing a problem in 2d rotations. A triangle is draw by using opengl drawing primitive GL_LINES.


方案是我想使用ER键旋转该三角形,并通过按up down left right箭头键沿其旋转轴平移该三角形.

Scenario is i want to rotate this triangle by using E and R key and translate this triangle along its rotation axis by pressing up down left right arrow keys.


但是现在三角形是旋转的,但不会沿其旋转轴平移.例如,用简单的词来说,当用户按下箭头键时,我将对象旋转90度角,它不会将三角形转换为90度角,而只是将其平移上下简单的对象,我受困于此.
这是我的代码:

But now triangle is rotate but doesn't translate along it's rotate axis.For example in simple words i rotate object 90 degree angle when user press up arrow key it doesn't translate that triangle to 90 degree angle it's just translate that object simple up and down I'm stuck on this.
This is my code:

#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;
}

推荐答案

好,我在阅读代码时误解了您的代码,但我在自己的PC机上将其复制了.

Ok, I misunderstood your code when I read it but I reproduced it on my pc.

正如我在评论中说的那样,转换的常见顺序是您当前正在执行的TRS(翻译,然后旋转,然后缩放).这样,您的对象将首先围绕原点缩放,然后围绕自身旋转,然后才平移到另一个点.

The common order for transforms, as I said in the comments, is what you're currently doing TRS (Translation followed by Rotation followed by Scaling). This way your object will first scale around the origin, then rotate around itself and only then be translated to another point.

我从您的问题中了解到的是,您希望对象绕一个点旋转,而不是在屏幕参考中移动(始终向上等),而是希望它相对于其新的前向矢量进行相对移动,或者旋转轴.然后,您必须将旋转放置在之前之前.

What I understood from your question is that you want the object to rotate around a point and then instead of moving in the screen referential (up is always up, etc) you want it to move relatively to it's new forward vector, or rotation axis. Then you have to place the rotation before the translation.

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

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

Now the object should rotate around the origin and move relatively to the current rotation axis. In addition, if you want to rotate around another point, you can also add another translation before the rotation.

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

读为,将对象平移到点(posX, posY),围绕中心点(centerX, centerY)沿轴(0,0,1)旋转对象.

This reads as, translate object to point (posX, posY), rotate object in axis (0,0,1) around center point (centerX, centerY).

Edit2: 如果centerX和centerY是(0,0),即原点,则外观如下.三角形开始于(0,0)的中心.

Here's how it looks if centerX and centerY are (0,0), ie the origin. The triangle starts centered at (0,0).

Edit3:

从注释中,您需要更改输入.使用您原始问题中的转换,即.旋转之前进行翻译.

From the comments, you'd need to change your input. Use the transforms that you had in your original question, ie. Translation before Rotation.

// 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,因此必须相应地将参数调整为三角函数.

Of course, change the values as you see fit. Don't forget that trigonometric functions take values in radians. Also, since your object is facing upwards by default then using angle 0 direction (0,1) corresponds to angle 90 in conventional maths, so you have to adjust the parameters to the trignometric functions accordingly.

这篇关于OpenGL对象无法平移到旋转轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆