用OpenGL绘制旋转的机器人手臂

来源:互联网 发布:金山网络测速 编辑:程序博客网 时间:2024/04/27 23:22


代码如下:

#include <GL/glut.h>#include <stdlib.h>#include <cmath>using namespace std;const GLfloat PI=3.14;static int shoulder = 0, elbow = 0;//shoulder:肩部角度,elbow: 肘部角度/// record the state of mouseGLboolean mouserdown = GL_FALSE;GLboolean mouseldown = GL_FALSE;GLboolean mousemdown = GL_FALSE;/// when a mouse-key is pressed, record current mouse position static GLint mousex = 0, mousey = 0;static GLfloat center[3] = {0.0f, 0.0f, 0.0f}; /// center positionstatic GLfloat eye[3]; /// eye's positionstatic GLfloat yrotate = PI/4; /// angle between y-axis and look directionstatic GLfloat xrotate = PI/4; /// angle between x-axis and look directionstatic GLfloat celength = 20.0f;/// lenght between center and eyestatic GLfloat mSpeed = 0.4f; /// center move speedstatic GLfloat rSpeed = 0.02f; /// rotate speedstatic GLfloat lSpeed = 0.4f; /// reserved/// calculate the eye position according to center position and angle,lengthvoid CalEyePostion(){if(yrotate > PI/2.2) yrotate = PI/2.2;   /// 限制看得方向if(yrotate < 0.01)  yrotate = 0.01;if(xrotate > 2*PI)   xrotate = 0.01;if(xrotate < 0)   xrotate = 2 * PI;if(celength > 50)  celength = 50;     ///  缩放距离限制if(celength < 5)   celength = 5;/// 下面利用球坐标系计算 eye 的位置,eye[0] = center[0] + celength * sin(yrotate) * cos(xrotate);  eye[2] = center[2] + celength * sin(yrotate) * sin(xrotate);eye[1] = center[1] + celength * cos(yrotate);}/// center movesvoid MoveBackward()              /// center 点沿视线方向水平向后移动{center[0] += mSpeed * cos(xrotate);center[2] += mSpeed * sin(xrotate);CalEyePostion();}void MoveForward(){center[0] -= mSpeed * cos(xrotate);center[2] -= mSpeed * sin(xrotate);CalEyePostion();}/// visual angle rotatesvoid RotateLeft(){xrotate -= rSpeed;CalEyePostion();}void RotateRight(){xrotate += rSpeed;CalEyePostion();}void RotateUp(){yrotate += rSpeed;CalEyePostion();}void RotateDown(){yrotate -= rSpeed;CalEyePostion();}/// CALLBACK func for keyboard pressesvoid KeyFunc(unsigned char key, int x, int y){switch(key){case 'a': RotateLeft(); break;case 'd': RotateRight();break;case 'w': MoveForward(); break;case 's': MoveBackward(); break;case 'q': RotateUp(); break;case 'e': RotateDown(); break;}glutPostRedisplay();}/// CALLBACK func for mouse kicksvoid MouseFunc(int button, int state, int x, int y){if(state == GLUT_DOWN){if(button == GLUT_RIGHT_BUTTON) mouserdown = GL_TRUE;if(button == GLUT_LEFT_BUTTON) mouseldown = GL_TRUE;if(button == GLUT_MIDDLE_BUTTON)mousemdown = GL_TRUE;}else{if(button == GLUT_RIGHT_BUTTON) mouserdown = GL_FALSE;if(button == GLUT_LEFT_BUTTON) mouseldown = GL_FALSE;if(button == GLUT_MIDDLE_BUTTON)mousemdown = GL_FALSE;}mousex = x, mousey = y;}/// CALLBACK func for mouse motionsvoid MouseMotion(int x, int y){if(mouserdown == GL_TRUE){       /// 所除以的数字是调整旋转速度的,随便设置,达到自己想要速度即可xrotate += (x - mousex) / 80.0f;     yrotate -= (y - mousey) / 120.0f;}if(mouseldown == GL_TRUE){celength += (y - mousey) / 25.0f;}mousex = x, mousey = y;CalEyePostion();glutPostRedisplay();}void LookAt()            /// 调用 gluLookAt(), 主要嫌直接调用要每次都写好几个参数。。{CalEyePostion();gluLookAt(eye[0], eye[1], eye[2],center[0], center[1], center[2],0, 1, 0);}void init(void){glClearColor(0.0f, 0.0f, 0.0f, 0.0f);glShadeModel(GL_FLAT);}void display(void){glClear(GL_COLOR_BUFFER_BIT);glPushMatrix();//把当前的变换矩阵压入OpenGL内部栈中,用以保存当前矩阵//画机器人的上臂glTranslatef(-1.0f, 0.0f, 0.0f);//用平移矩阵乘当前矩阵,格式为:glTranslatef(x,y,z)glRotatef((GLfloat) shoulder, 0.0f, 0.0f, 1.0f);//用旋转矩阵乘当前矩阵,格式为glRotatef (角度,x轴,y轴,z轴),这里是绕Z轴旋转glTranslatef(1.0f, 0.0f, 0.0f);//再用平移矩阵乘当前矩阵,注意顺序glPushMatrix();//变换矩阵压栈glScalef(2.0f, 0.4f, 1.0f);//用缩放矩阵乘以当前矩阵,格式为glScalef(x缩放比例,y缩放比例,z缩放比例)glutWireCube(1.0f);//glut库函数,画一个三维的Cube,参数为边长glPopMatrix();//弹栈,现在矩阵恢复到使用缩放前的样子//画机器人的前臂,请注意平移矩阵和旋转矩阵的变化glTranslatef(1.0f, 0.0f, 0.0f);glRotatef((GLfloat) elbow, 0.0f, 0.0f, 1.0f);glTranslatef(1.0f, 0.0f, 0.0f);glPushMatrix();glScalef(2.0f, 0.4f, 1.0f);glutWireCube(1.0f);glPopMatrix();glPopMatrix();glFlush();}void reshape (int width, int height){glViewport(0, 0, width, height);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(65.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);//建立一个透视投影视图体,格式为:gluPerspective(视域的角度,宽高比,视点到近裁剪面的距离(总为正),视点到远裁剪面的距离(总为正))glMatrixMode(GL_MODELVIEW);LookAt();glLoadIdentity();glTranslatef(0.0f, 0.0f, -5.0f);//用平移矩阵乘当前矩阵,注意,这会将所有绘制过程中绘制的物体平移}void keyboard(unsigned char key, int x, int y){switch (key){case 'a'://处理四个按键,改变旋转角度,转动手臂shoulder = (shoulder + 5) % 360;glutPostRedisplay();//重画break;case 'd':shoulder = (shoulder - 5) % 360;glutPostRedisplay();break;case 'q':elbow = (elbow + 5) % 360;glutPostRedisplay();break;case 'e':elbow = (elbow - 5) % 360;glutPostRedisplay();break;case 'x':exit(0);break;default:break;}}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(1000,1000);glutInitWindowPosition(100, 100);glutCreateWindow("1352453_王用");init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);//键盘按键glutMouseFunc(MouseFunc);//鼠标按键glutMotionFunc(MouseMotion);//鼠标移动glutMainLoop();return 0;}


0 0
原创粉丝点击