c++ - 围绕与原点不同的点旋转

标签 c++ opengl 3d rotation translation

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


编辑:添加代码

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

#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 函数以原点为引用。为了围绕一个点(在这种情况下是您的相机坐标)旋转,您应该将相机位置平移到原点(相应地平移所有对象)然后应用旋转功能。然后您可以将相机平移回来(与所有对象一起)

假设你的相机位置是 (a,b,c) 所以你的代码应该是这样的:

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

关于c++ - 围绕与原点不同的点旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26743207/

相关文章:

opengl - glew32.dll 运行时错误

使用 gluLookAt() 的 OpenGL FPS 相机

c++ - QT OpenGL无法完全渲染立方体吗?

math - 将 3D 点转换为 2D

Python - 二维 Numpy 数组的交集

c++ - C-Free 和 MySQL 连接

c++ - 虚拟基类函数中派生类的大小

c++ - 修改排序数组还是每次都对数组排序?

C++程序在工厂模式中调用父类(super class)方法而不是子类方法

java - OpenGL 着色器 : glLinkProgram() and glValidateProgram() doesn't work