C++ 在OpenGL中沿对象自身的轴旋转对象
所以我有一个立方体,我想绕着它的三个轴(立方体的轴,而不是窗口)旋转。正如许多其他类似的问题所指出的,只要我只朝一个方向旋转,我的旋转就会起作用,但当我开始混合它们时,我会得到奇怪的结果。特别是,无论立方体如何旋转,围绕y轴的旋转始终围绕窗口的y轴旋转 我的绘图代码如下:C++ 在OpenGL中沿对象自身的轴旋转对象,c++,opengl,graphics,3d,rotation,C++,Opengl,Graphics,3d,Rotation,所以我有一个立方体,我想绕着它的三个轴(立方体的轴,而不是窗口)旋转。正如许多其他类似的问题所指出的,只要我只朝一个方向旋转,我的旋转就会起作用,但当我开始混合它们时,我会得到奇怪的结果。特别是,无论立方体如何旋转,围绕y轴的旋转始终围绕窗口的y轴旋转 我的绘图代码如下: glMatrixMode(GL_MODELVIEW) ; glLoadIdentity(); gluLookAt(0.0, 5.0, 15.0, 0.0, 0.0, 0.0, 0
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity();
gluLookAt(0.0, 5.0, 15.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(theta_y,0,1,0);
glRotatef(theta_x,1,0,0);
glRotatef(theta_z,0,0,1);
draw_cube();
glPopMatrix();
float cube_x[] = {1.0f,0.0f,0.0f,0.0f};
float cube_y[] = {0.0f,1.0f,0.0f,0.0f};
float cube_z[] = {0.0f,0.0f,1.0f,0.0f};
这个问题似乎非常准确地描述了我想做的事情,而公认的答案似乎是我想做的事情,但他提供的链接已经失效
从我在链接问题中收集到的信息来看,我的z-旋转是首先执行的,这意味着在我的x-旋转(下一个)中,我需要,而不是围绕(1,0,0)旋转,我将围绕(-sin(theta_z),cos(theta_z),0)旋转。但是对于第三个旋转,他只给出了链接,说它变得“非常复杂”。现在链接死了,我不知道如何进行第三个旋转
编辑:
根据回复,我添加了三个向量:cube_x
、cube_y
和cube_z
,以保持我的多维数据集的当前轴。它们初始化如下:
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity();
gluLookAt(0.0, 5.0, 15.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(theta_y,0,1,0);
glRotatef(theta_x,1,0,0);
glRotatef(theta_z,0,0,1);
draw_cube();
glPopMatrix();
float cube_x[] = {1.0f,0.0f,0.0f,0.0f};
float cube_y[] = {0.0f,1.0f,0.0f,0.0f};
float cube_z[] = {0.0f,0.0f,1.0f,0.0f};
回到我的绘图功能中,我对其进行了更改,以便围绕这些轴进行旋转,而不是像以前那样围绕全局轴进行旋转。执行三次旋转后,我调用glGetFloatv
获取当前矩阵,并使用一个新函数update\u vector
用它们的新值填充立方体向量。这些都包括在下面:
void update_vector(float vector[],float matrix[]) {
vector[0] = matrix[0]*vector[0] + matrix[1]*vector[1] + matrix[2]*vector[2] + matrix[3]*vector[3];
vector[1] = matrix[4]*vector[0] + matrix[5]*vector[1] + matrix[6]*vector[2] + matrix[7]*vector[3];
vector[2] = matrix[8]*vector[0] + matrix[9]*vector[1] + matrix[10]*vector[2] + matrix[11]*vector[3];
vector[3] = matrix[12]*vector[0] + matrix[13]*vector[1] + matrix[14]*vector[2] + matrix[15]*vector[3];
}
void my_display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ;
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity();
gluLookAt(0.0, 5.0, 15.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(theta_y,cube_y[0],cube_y[1],cube_y[2]);
glRotatef(theta_x,cube_x[0],cube_x[1],cube_x[2]);
glRotatef(theta_z,cube_z[0],cube_z[1],cube_z[2]);
//get the current matrix
float my_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, my_matrix);
//Multiply the matrix by each of my vectors
update_vector(cube_x,my_matrix);
update_vector(cube_y,my_matrix);
update_vector(cube_z, my_matrix);
make_cube();
glPopMatrix();
/* buffer is ready */
glutSwapBuffers();
return ;
}
现在,当我试着绕y轴旋转时,立方体似乎在绕x轴旋转之前,沿着几个轴摆动了一点。围绕Z旋转也会做同样的事情。似乎只有绕x轴旋转才有效
编辑:解决方案:
在下面的评论中,加文提到Y轴旋转总是首先发生。这就是问题的全部。通过添加一个标志“旋转”(ROT)并根据我尝试旋转的轴设置它,我可以对旋转进行排序,以便最后旋转轴。我不知道什么是复杂的。OpenGL为您计算矩阵。记住矩阵乘法是关联的,所以如果Rx etc是绕坐标轴旋转,那么Rx.Ry表示绕y旋转,然后是x。它始终是关于坐标轴的,无论您的形状在此期间结束于何处。顺便说一句,OpenGL ES是右手的,不像传统的OpenGL 观看后,必须平移立方体的负位置,进行旋转,然后平移回立方体的位置 这是一个链接,你说这篇文章很可能是重复的,所以如果我的立方体位于原点的中心(在[1,1,1]和[-1,-1,-1]),我的注视点位于位置(0,5,-15),那么我首先平移(0,-5,15),旋转,平移(0,5,-15),然后绘制立方体?我实际上认为这可能与此有关。看了之后,我平移(0,5,-15),检查GLGetFloatv告诉我现在在原点(最后4个元素是0,0,0,1)。我执行上面所述的旋转,平移(0,-5,15)回到我的矩阵之前的位置,然后弹出我的矩阵。然而,当我运行这个程序时,我似乎在立方体上被放大了,没有其他变化。嗯,我想你可能只是对旋转的顺序有点困惑。你发布的原始代码运行良好(如我所料)。只需将“推送矩阵”放在查看之前。也许你只需要改变旋转的顺序,因为Y旋转总是首先发生在你的代码中,而且当你推动和弹出矩阵时,它总是,巧合地,与屏幕方向相同。我希望这是有意义的。glClearColor(0.0f,0.0f,0.0f,0.0f);glClear(GLU颜色缓冲位);glPushMatrix();gluLookAt(0,0.5,-5,0,0,0,0,1,0);glRotatef(θ,0.0f,0.0f,1.0f);glRotatef(θ,0.0f,1.0f,0.0f);glRotatef(θ,1.0f,0.0f,0.0f);drawcube();glPopMatrix();先推后看使它像最初一样工作。在这种状态下,我可以沿立方体的x轴或z轴旋转立方体,但不能在y轴上旋转立方体;它只是围绕窗口的y轴旋转,而不是穿过立方体的边的轴,这些边最初分别面向(0,1,0)和(0,-1,0)