围绕与原点不同的点旋转

2022-01-16 00:00:00 opengl translation 3d rotation c++

我正在尝试使用 glTranslate/glRotate 编写相机代码.为了实现查找/查找功能,我需要渲染空间中的所有对象围绕一个点(即相机"所在的位置)旋转,该点通常与原点不同.尽管如此,事情仍然围绕原点旋转.有没有办法指定不同的点?

I'm trying to code a camera with glTranslate/glRotate. To implement the look-up / look-down functions I need all the objects in my rendering space to rotate around a point (that is, where the "camera" is at), point which usually differs from the origin. Still, things keep rotating around the origin. Is there a way to specify a different point?

添加代码

感谢您的快速回复.似乎无论如何我都无法让它正常工作,所以我决定添加我的代码;如果有人可以查看它并告诉我需要进行哪些更改才能翻译/旋转/翻译回来,我将不胜感激.

Thanks for your fast reply. It seems that I can't get it working right no matter what, so I've decided to add my code; I'd much appreciate if someone could take a look at it and tell me what changes are needed in order to translate/rotate/translate back.

#include <iostream>
#include <cmath>
#include <GLUT/GLUT.h>

const double roaming_step = .13;
double z_offset = .0;
double y_offset = .0;
double x_offset = .0;

const double angle_step = 1.5;
double angle_xz = .0;
double angle_yz = .0;

bool keyStates[256] = { false };

void drawFloor()
{
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_QUADS);
        glVertex3f(-3.0, -1.0, 3.0);
        glVertex3f(-3.0, -1.0, -3.0);
        glVertex3f(3.0, -1.0, -3.0);
        glVertex3f(3.0, -1.0, 3.0);
    glEnd();
}

void drawBalls()
{           
    glTranslatef(-3.0, -.5, -3.0);
    glColor3f(.8, .1, .1);

    for(int i = 0; i < 3; i++)
    {
        glPushMatrix();

        glTranslatef(.0, -.5, i * 3);

        for(int j = 0; j < 3; j++)
        {
            glPushMatrix();

            glTranslatef(j * 3, .0, .0);
            glutSolidSphere(.5, 20, 20);

            glPopMatrix();
        }

        glPopMatrix();
    }
}

void keyPressed(unsigned char key, int x, int y)
{
    keyStates[key] = true;
}

void keyReleased(unsigned char key, int x, int y)
{
    keyStates[key] = false;
}

void keyboardOperations()
{   
    if(keyStates['w'])
        z_offset += roaming_step;

    if(keyStates['s'])
        z_offset -= roaming_step;

    if(keyStates['a'])
        x_offset += roaming_step;

    if(keyStates['d'])
        x_offset -= roaming_step;

    if(keyStates['i'])
    {
        angle_xz -= angle_step;

        if(angle_xz < .0)
            angle_xz += 360.0;
    }

    if(keyStates['o'])
    {
        angle_xz += angle_step;

        if(angle_xz >= 360.0)
            angle_xz -= 360.0;
    }

    if(keyStates['u'])
    {
        angle_yz -= angle_step;

        if(angle_yz < .0)
            angle_yz += 360.0;
    }

    if(keyStates['j'])
    {
        angle_yz += angle_step;

        if(angle_yz >= 360.0)
            angle_yz -= 360.0;
    }

    if(keyStates['q'])
        exit(0);
}

// I guess it has to be done in this function
// but didn't get how
void camera()
{
    glLoadIdentity();

    // Forward / Backward
    glTranslated(.0, .0, z_offset);

    // Left / Right
    glTranslated(x_offset, .0, .0);

    // XZ Rotation
    glRotated(angle_xz, .0, 1.0, .0);

    // YZ Rotation
    glRotated(angle_yz, 1.0, .0, .0);
}

void display(void)
{   
    keyboardOperations();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    camera();

    drawFloor();
    drawBalls();

    glutSwapBuffers();
}

void reshape(int width, int height)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0, 0, width, height);

    GLdouble aspect = (GLdouble) width / (GLdouble) height;
    gluPerspective(60, aspect, 1, 100);

    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{   
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("openGLtest3");
    glClearColor(.0, .0, .0, .0);

    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(display);

    glutIgnoreKeyRepeat(true);
    glutKeyboardFunc(keyPressed);
    glutKeyboardUpFunc(keyReleased);

    glutMainLoop();

    return 0;
}

推荐答案

在openGL中,glRotation函数以origin作为参考.为了围绕一个点旋转(在这种情况下是您的相机坐标),您应该将相机位置平移到原点(相应地平移所有对象),然后应用旋转功能.然后您可以将相机平移回来(与所有对象一起)

In openGL, glRotation fuction takes origin as a reference. In order to rotate around a point (your camera coordinate in this case) you should translate your camera position to the origin (Translate all your objects accordingly) and then apply rotation function.And then you can translate your camera back (with all your objects)

假设您的相机位置是 (a,b,c),因此您的代码应该类似于:

lets say your camera position is (a,b,c) so your code should be something like :

foreach object
{
    glPushMatrix();
    glTranslate(a,b,c);
    glRotate(...);
    glTranslate(-a,-b,-c);
    //render
    glPopMatrix();
}

相关文章