如何在OpenGL中围绕某个点(非原点)旋转2D图形?

4

使用glrotatef()函数可以将图形绕原点旋转指定角度。如何在不手动使用变换矩阵的情况下,将同一图形绕另一点旋转?谢谢!

void display(){
    glClear(GL_COLOR_BUFFER_BIT);
    gluOrtho2D(0,499,0,499);
    glMatrixMode(GL_PROJECTION);
    glColor3f(1,0,0);
    drawhouse();
    glFlush();
    glColor3f(0,0,1);
    glTranslatef(0.5 ,0.5,0.5);
    glRotatef(45,1,1,1);
    glTranslatef(-0.5 ,-0.5,-0.5);
    drawhouse();
    glFlush();
}

这里是一个截图,显示了发生的情况。 http://postimage.org/image/q81bhupw/

使用glRotatef时,您实际上正在使用旋转矩阵,但您可能没有意识到。但我知道您的意思,John的答案将是您的首选方法。 - Christian Rau
John的回答有问题,对吧?我已经在他的回答下添加了一条评论... 我刚试了一下,它不是那样工作的。 - Amal Antony
John的答案是正确的。他只是假设你知道如何正确应用这些操作!看看我的答案。 - Christian Rau
2个回答

7

基本上:

如果你想绕 P 旋转,先将图形平移 -P (这样点 P 就移到了坐标系原点),然后进行旋转操作,最后再将图形平移 P (这样原点就回到了点 P 的位置)。

glTranslatef(P.x, P.y, P.z);
glRotatef(angle, A.x, A.y, A.z);
glTranslatef(-P.x, -P.y, -P.z);

(注:这是“反向顺序”,因为最后添加的转换是OpenGL规则下应用的第一个。)
因此,在您的设置代码中,您需要进行以下调用:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 499, 0, 499);
glMatrixMode(GL_MODELVIEW);

然后你的display()方法应该像这样:

void display() {
    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0.5f, 0.5f, 0.5f);
    glRotatef(45.f, 1.f, 1.f, 1.f);
    glTranslatef(-0.5f, -0.5f, -0.5f);
    glColor3f(0.f, 0.f, 1.f);
    drawhouse();
    glFlush();
}

1
即使您将P移动到原点,原点本身是否会再次被移位到一个新点,并且旋转是围绕新原点进行的? - Amal Antony
但是我刚刚写了以下代码,就出现了那个问题: drawhouse();
glTranslatef(0.5 ,0.5,0.5); glRotatef(45,1,1,1); glTranslatef(-0.5 ,-0.5,-0.5); drawhouse();
- Amal Antony
我已将其添加到主帖中,John,你的答案非常有道理,但出于某种原因似乎不起作用。 - Amal Antony
2
你正在调用 glMatrixMode(GL_PROJECTION),然后再也没有调用 glMatrixMode(GL_MODELVIEW),所以你没有改变你认为的东西。此外,你不应该在每个显示调用中两次绘制场景(甚至不应该每个显示调用都更改投影矩阵)。我认为你的问题与旋转无关。 - John Calsbeek
那么我该如何解决我的问题呢?我已经添加了一个屏幕截图来显示输出结果。 - Amal Antony
显示剩余2条评论

3

你的代码存在很多问题。首先,你必须在模型视图矩阵上应用变换而不是投影矩阵。其次,你应该将变换包装在glPushMatrix/glPopMatrix中,否则,它们在渲染下一帧时不会被撤销。第三,你应该在投影矩阵而不是模型视图矩阵上应用gluOrtho2d

根据约翰的答案,你的代码应该如下:

void display(){
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0,499,0,499);
    glMatrixMode(GL_MODELVIEW);
    glColor3f(1,0,0);
    drawhouse();
    glFlush();
    glColor3f(0,0,1);
    glPushMatrix();
        glTranslatef(0.5 ,0.5,0.5);
        glRotatef(45,1,1,1);
        glTranslatef(-0.5 ,-0.5,-0.5);
        drawhouse();
    glPopMatrix();
    glFlush();
}

编辑:即使你害怕矩阵,我建议你阅读一些关于向量和矩阵操作以及转换的入门材料。你还应该阅读一些关于OpenGL的入门材料,以真正理解它的工作原理,特别是状态机原理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接