图形学_assign3_正十二面体

来源:互联网 发布:淘宝单怎么刷 编辑:程序博客网 时间:2024/04/29 06:58
实现漫游者模式控制正十二面体的转动和视角平移
/*****************************Author :TanrunjTime   :2014-03-27 23:30School :SYSU school of softwareProgram:Tracking DodecahedronReference:http://blog.csdn.net/pleasecallmewhy/article/details/8179302*******************************/#include "stdafx.h"#include <stdlib.h>#include <GL/glut.h>#include <math.h>#define PI 3.14159  //当前窗口大小int  winWidth, winHeight; //旋转角度,法向量 ,位移向量float angle = 0.0, nor_vec[3], trans[3];  bool click_and_move = false;//鼠标点击下移动bool rotate = false;//旋转标志bool tracking = false;//跟踪球的视觉变换float last_position[3] = {0.0F, 0.0F, 0.0F};  //记录之前位置int current_x, current_y;//鼠标当前位置int start_x, start_y;//鼠标开始移动位置 int click;//鼠标点击状态     0:左键 1:右键 bool fill;//是否填充五边形   false:不填充 true:填充//20个顶点数组GLfloat vertices[][3] = {{1.214124,0.000000,1.589309},{0.375185,1.154701,1.589309},{-0.982247,0.713644,1.589309}, {-0.982247,-0.713644,1.589309}, {0.375185,-1.154701,1.589309},  {1.964494,0.000000,0.375185}, {0.607062,1.868345,0.375185}, {-1.589309,1.154701,0.375185},{-1.589309,-1.154701,0.375185},{0.607062,-1.868345,0.375185},{1.589309,1.154701,-0.375185},{-0.607062,1.868345,-0.375185},{-1.964494,0.000000,-0.375185},{-0.607062,-1.868345,-0.375185},{1.589309,-1.154701,-0.375185},{0.982247,0.713644,-1.589309},{-0.375185,1.154701,-1.589309},{-1.214124,0.000000,-1.589309},{-0.375185,-1.154701,-1.589309},{0.982247,-0.713644,-1.589309}};//12个面的颜色数组GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0},{0,0,0},{1,0,0},{1,1,0},{0,1,0}};//每个面的5个顶点索引GLubyte cubeIndices[][5]={0,1,2,3,4,0,5,10,6,1, 1,6,11,7,2, 2,7,12,8,3,3,8,13,9,4, 4,9,14,5,0, 15,10,5,14,19,16,11,6,10,15, 17,12,7,11,16, 18,13,8,12,17,19,14,9,13,18, 19,18,17,16,15};  //初始化void init(void){fill = true;gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);  glEnableClientState(GL_COLOR_ARRAY);  glEnableClientState(GL_VERTEX_ARRAY);  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);  glutInitWindowSize(500, 500);  glutCreateWindow("tanrunj");  }//画正五边形void Pentagon(GLubyte a[5])  {  if(fill)glBegin(GL_POLYGON); elseglBegin(GL_LINE_STRIP);for(int i =0;i<5;i++)glVertex3fv(vertices[a[i]]);  glEnd();  }  //绘制函数void MyDisplay(void)  {  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  /* 视点矩阵变换 */  if (tracking)  {  if(!click)glRotatef(angle, nor_vec[0], nor_vec[1], nor_vec[2]);  elseglTranslatef(trans[0],trans[1],trans[2]);}  for(int i = 0 ;i<12;i++){ glColor3fv(colors[i]);  Pentagon(cubeIndices[i]);}glutSwapBuffers();  }  void spinCube()  {  if (rotate) glutPostRedisplay();  }  //将鼠标位置映射到半球上并记录在数组v上//void trackball_ptov(int x, int y, int width, int height, float v[3])  {  float d, a;  v[0] = (2.0F*x - width) / width;  v[1] = (height - 2.0F*y) / height;  d = (float) sqrt(v[0]*v[0] + v[1]*v[1]);  v[2] = (float) cos((PI/2.0F) * ((d < 1.0F) ? d : 1.0F));  a = 1.0F / (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);  v[0] *= a;  v[1] *= a;  v[2] *= a;  }  //鼠标滑动                                                                                                                                              void mouseMotion(int x, int y)  {  float curPos[3], dx, dy, dz;  trackball_ptov(x, y, winWidth, winHeight, curPos);  if(click_and_move)  {  //三个方向的微分dx = curPos[0] - last_position[0];  dy = curPos[1] - last_position[1];  dz = curPos[2] - last_position[2];  if (dx || dy || dz) {  if(!click){//转动角度大小angle = 90.0F * sqrt(dx*dx + dy*dy + dz*dz);  //两个位置向量叉乘得旋转的法向量nor_vec[0] = last_position[1]*curPos[2] - last_position[2]*curPos[1];  nor_vec[1] = last_position[2]*curPos[0] - last_position[0]*curPos[2];  nor_vec[2] = last_position[0]*curPos[1] - last_position[1]*curPos[0];  }else{trans[0] = curPos[0] - last_position[0];trans[1] = curPos[1] - last_position[1];trans[2] = curPos[2] - last_position[2];}//将当前位置记录为历史位置last_position[0] = curPos[0];  last_position[1] = curPos[1];  last_position[2] = curPos[2];  }  }  glutPostRedisplay();  }  //鼠标按下响应函数void MouseStart(int x, int y)  {  //标记鼠标开始滑动click_and_move = true;  rotate = false;  tracking=true; //初始化起末位置start_x = x; start_y = y;  current_x = x; current_y = y;  trackball_ptov(x, y, winWidth, winHeight, last_position);  }  //鼠标松开响应函数void MouseStop(int x, int y)  {  click_and_move = false;  click = 0;if (start_x != x || start_y != y) {  rotate = true;  } else {  angle = 0.0F;  rotate = false;  tracking = false;  }  }  void mouseButton(int button, int state, int x, int y)  {  //左键处理if(button==GLUT_LEFT_BUTTON) {click = 0;switch(state)  {  //按下case GLUT_DOWN:  y=winHeight-y;  MouseStart(x,y);  break;  //放开case GLUT_UP:  MouseStop(x,y);  break;  }  }//右键处理if(button==GLUT_RIGHT_BUTTON){click = 1;switch (state){case GLUT_DOWN:y=winHeight-y;MouseStart(x,y);  break;case GLUT_UP:MouseStop(x,y);  break;}}}  //改变窗口大小时处理视点void MyReshape(int w, int h)  {  glViewport(0,0,w,h);//设置视口glMatrixMode(GL_PROJECTION);//指明当前矩阵为GL_PROJECTIONglLoadIdentity();//将当前矩阵置换为单位阵if (w <= h)  glOrtho(-4.0, 4.0, -3.0 * (GLfloat) h / (GLfloat) w,  //定义投影矩阵5.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);  else  glOrtho(-4.0 * (GLfloat) w / (GLfloat) h,  4.0 * (GLfloat) w / (GLfloat) h, -3.0, 5.0, -10.0, 10.0);  glMatrixMode(GL_MODELVIEW);//指明当前矩阵为GL_MODELVieWwinHeight = h ;winWidth = w;}  void middle_click(int id){fill = id;}void keyButton(unsigned char k ,int xx,int yy){if(k==27)exit(0);return ;}//程序入口void main(int argc, char **argv)  {  /* need both double buffering and z buffer */  glutInit(&argc, argv);  init();glClearColor(1.0,1.0,1.0,1.0); glEnable(GL_DEPTH_TEST);glutReshapeFunc(MyReshape);  glutDisplayFunc(MyDisplay);  glutIdleFunc(spinCube);  //键盘响应glutKeyboardFunc(keyButton);//鼠标响应glutMouseFunc(mouseButton);glutMotionFunc(mouseMotion);//中键菜单int mid_menu = glutCreateMenu(middle_click);glutAddMenuEntry("Fill",1);glutAddMenuEntry("Unfill",0);glutAttachMenu(GLUT_MIDDLE_BUTTON);glutMainLoop();  }
鼠标跟踪控制多面体
1 0
原创粉丝点击