OpenGL 对象不转换为旋转轴
Posted
技术标签:
【中文标题】OpenGL 对象不转换为旋转轴【英文标题】:OpenGL object doesn't translate to rotation axis 【发布时间】:2016-03-14 06:54:50 【问题描述】:我在 2d 旋转中遇到问题。使用opengl
绘制原语GL_LINES
绘制三角形。
场景是我想使用E
和R
键来旋转这个三角形,并通过按up
down
left
right
箭头键沿其旋转轴平移这个三角形。
但是现在三角形是旋转的,但不会沿着它的旋转轴平移。例如,简单来说,当用户按下向上箭头键时,我将对象旋转 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;
【问题讨论】:
使用当前代码,您的对象围绕原点旋转,对吗?变换的常见顺序是 TRS,因此对象围绕自身旋转/缩放。但我不明白你想要达到什么目的以及有什么问题。你能显示一个 GIF 吗? @aslg 我现在编辑我的问题,你明白了 【参考方案1】:好的,我在阅读时误解了您的代码,但我在我的电脑上复制了它。
正如我在 cmets 中所说的,变换的常见顺序是您当前正在执行的 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)
,围绕中心点(centerX, centerY)
沿轴(0,0,1)
旋转对象。
编辑2:
如果 centerX 和 centerY 为(0,0)
,即原点,则如下所示。三角形以(0,0)
为中心开始。
编辑3:
在 cmets 中,您需要更改输入。使用您在原始问题中的转换,即。旋转前的翻译。
// 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,因此您必须相应地调整三角函数的参数。
【讨论】:
什么是centerX
centerY
我正在使用相同的顺序,现在翻译发生在相同的旋转中。但是当再次从它的新位置旋转这个对象时,它不会从它的原点旋转。
@hamel123 我已经上传了最终结果的 gif。这是您想要实现的目标吗?
是的,但是为什么它从中心旋转我想从它上次停留的确切位置旋转
@hamel123 所以基本上,你希望你的三角形移动。像自上而下游戏中的 2D 角色?以上是关于OpenGL 对象不转换为旋转轴的主要内容,如果未能解决你的问题,请参考以下文章