C++ 围绕绝对轴旋转三维模型
我不知道如何将鼠标拖动转换为围绕图像平面的Ox和Oy旋转。C++ 围绕绝对轴旋转三维模型,c++,math,opengl,rotation,C++,Math,Opengl,Rotation,我不知道如何将鼠标拖动转换为围绕图像平面的Ox和Oy旋转。 我按照的第一个答案,将modelView矩阵存储在一个数组中,并在每次鼠标移动时更新它alpha和beta与鼠标从前一位置的增量成比例 此代码在鼠标移动时更新旋转: glLoadMatrixf(currentModelViewMatrix); glRotatef(beta,0,1,0); glRotatef(alpha,1,0,0); glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMa
我按照的第一个答案,将modelView矩阵存储在一个数组中,并在每次鼠标移动时更新它
alpha
和beta
与鼠标从前一位置的增量成比例
此代码在鼠标移动时更新旋转:
glLoadMatrixf(currentModelViewMatrix);
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
我从解释的结尾就尝试了这个解决方案,但没有产生任何影响
只有beta
给出的旋转是绝对的,而alpha
给出的旋转是围绕模型中的一个轴旋转的,当围绕第一个轴旋转时,该轴会旋转。我不知道如何使第二个旋转是绝对的。现在的方式对用户来说似乎并不直观
编辑: 增量代码:
GLfloat currentModelViewMatrix[16];
GLfloat whole[16];
void glob()
{
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX,whole);
alpha=beta=0;
}
在每个模型之前,加载矩阵:
glLoadMatrixf(whole);
完整代码:
#include "math.h"
#include "string.h"
#include "stdio.h"
#include "GL/freeglut.h"
#include "GL/gl.h"
#include "GL/glu.h"
float alpha,beta;
void key(int key, int x, int y)
{ printf("%d",key);
switch(key)
{ case GLUT_KEY_RIGHT:
printf("right\n");
break;
case GLUT_KEY_LEFT:
printf("left\n");
break;
case GLUT_KEY_UP:
printf("top\n");
break;
case GLUT_KEY_DOWN:
printf("bottom\n");
break;
}
glutPostRedisplay();
fflush(stdout);
}
void otherkeys(unsigned char key,int x,int y)
{ printf("%c\n",key);
fflush(stdout);
switch(key)
{ case '+':
printf("plus\n");
break;
case '-':
printf("minus\n");
break;
case 'w':
alpha+=10;
break;
case 's':
alpha-=10;
break;
case 'd':
beta+=10;
break;
case 'a':
beta-=10;
break;
}
glutPostRedisplay();
}
void drawCube()
{ int i,j,d;
glBegin(GL_LINES);
for(i=0;i<8;i++)
{ for(j=i+1;j<8;j++)
{ d=j^i;
if(d==1||d==2||d==4)
{ glVertex3i(i%2,i/2%2,i/4%2 );
glVertex3i(j%2,j/2%2,j/4%2 );
}
}
}
glEnd();
}
GLfloat currentModelViewMatrix[16];
GLfloat whole[16];
void glob()
{
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX,whole);
alpha=beta=0;
}
void renderFunction()
{ int i;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glRotatef(angle2,0.0,0.0,1.0);
gluPerspective(60, 1.333, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glColor3f(1.0,0.0,0.0);
for(i=1;i<8;i++)
{
glLoadMatrixf(whole);
glTranslatef(i*2.0,0,0);
drawCube();
}
glColor3f(0.0,1.0,0.0);
for(i=1;i<6;i++)
{
glLoadMatrixf(whole);
glTranslatef(0,i*2.0,0);
drawCube();
}
glColor3f(0.0,0.0,1.0);
for(i=0;i<5;i++)
{
glLoadMatrixf(whole);
glTranslatef(0,0,i*2.0);
drawCube();
}
glFlush();
}
/*mouse*/
int prevx,prevy,dx,dy;
void rotate(int dx,int dy)
{ printf("%f %f\n",dy/10.0,dy/10.0);
alpha=dy/2.0;
beta=dx/2.0;
glob();
}
void passive(int x,int y)
{ prevx=x;prevy=y;}
void active(int x,int y)
{ dx=x-prevx;
prevx=x;
dy=y-prevy;
prevy=y;
rotate(dx,dy);
}
void globinit()
{
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glGetFloatv(GL_MODELVIEW_MATRIX, whole);
}
int main (int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Open GL bla bla");
glutDisplayFunc(renderFunction);
glutIdleFunc(renderFunction);
glutSpecialFunc(key);
glutKeyboardFunc(otherkeys);
glutMotionFunc(active);
glutPassiveMotionFunc(passive);
globinit();
glutMainLoop();
return 0;
}
#包括“math.h”
#包括“string.h”
#包括“stdio.h”
#包括“GL/freeglut.h”
#包括“总账/总账h”
#包括“GL/glu.h”
浮动α,β;
无效键(整数键、整数x、整数y)
{printf(“%d”,键);
开关(钥匙)
{case GLUT_KEY_RIGHT:
printf(“右”);
打破
案例过剩\u键\u左:
printf(“左\n”);
打破
案例过多关键点:
printf(“top\n”);
打破
案例过量键关闭:
printf(“底部\n”);
打破
}
再发现();
fflush(stdout);
}
无效其他键(无符号字符键,整数x,整数y)
{printf(“%c\n”,键);
fflush(stdout);
开关(钥匙)
{大小写“+”:
printf(“plus\n”);
打破
案例'-':
printf(“减\n”);
打破
案例“w”:
α+=10;
打破
案例s:
α-=10;
打破
案例“d”:
β+=10;
打破
案例“a”:
β-=10;
打破
}
再发现();
}
void drawCube()
{int i,j,d;
glBegin(GL_行);
对于(i=0;i请尝试以下操作:
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
由于改变了顺序,旋转是在全局坐标系中执行的,而不是在局部坐标系中执行的。谢谢,它与平移配合得很好,因此不会绕原点旋转