Advertisement

OpenGL实现绕轴旋转

阅读量:

首先需要完成一个旋转操作,并且以便生成一个简化的三维模型。其背后的代码由老师提供。

复制代码
 void CSphereView::Display()

    
 {
    
 	GLUquadricObj* quad_obj = NULL;
    
 	if (quad_obj == NULL) quad_obj = gluNewQuadric();
    
 	gluQuadricDrawStyle(quad_obj, GLU_LINE);
    
 	gluQuadricNormals(quad_obj, GLU_SMOOTH);
    
  
    
 	glClear(GL_COLOR_BUFFER_BIT);
    
 	glColor3f(1.0, 1.0, 1.0);
    
 	glLoadIdentity();
    
  
    
 	//view
    
 	gluLookAt(-2.0, -1.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    
 	glPushMatrix();
    
  
    
 	//the first joint
    
 	if (selectedNum == 1) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	gluSphere(quad_obj, 1.0f, 20, 20);
    
  
    
 	//the first degree
    
 	glRotated(armsDegree[0].xy, 0, 0, 1);
    
 	glRotated(armsDegree[0].yz, 1, 0, 0);
    
 	glRotated(armsDegree[0].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the first arm
    
 	glPushMatrix();
    
 	glColor3f(1, 1, 1);
    
 	glTranslated(6, 0, 0);
    
 	glScaled(10, 2, 2);
    
 	DrawUnitCube();
    
 	glPopMatrix();
    
  
    
 	//draw the second joint
    
 	glTranslated(11.8, 0, 0);
    
 	glPushMatrix();
    
 	if (selectedNum == 2) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	gluSphere(quad_obj, 0.8f, 20, 20);
    
  
    
 	//the second degree
    
 	
    
 	glRotated(armsDegree[1].xy, 0, 0, 1);
    
 	glRotated(armsDegree[1].yz, 1, 0, 0);
    
 	glRotated(armsDegree[1].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the second arm
    
 	glColor3f(1, 1, 1);
    
 	glPushMatrix();
    
 	glTranslated(4.8, 0, 0);
    
 	glScaled(8, 1.5, 1.5);
    
 	DrawUnitCube();
    
 	glPopMatrix();
    
  
    
 	//draw the third joint
    
 	if (selectedNum == 3) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	glTranslated(9.4, 0, 0);
    
 	glPushMatrix();
    
 	gluSphere(quad_obj, 0.6f, 20, 20);
    
  
    
 	//the third degree
    
 	glRotated(armsDegree[2].xy, 0, 0, 1);
    
 	glRotated(armsDegree[2].yz, 1, 0, 0);
    
 	glRotated(armsDegree[2].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the third arm
    
 	glColor3f(1, 1, 1);
    
 	glPushMatrix();
    
 	glTranslated(2.6, 0, 0);
    
 	glScaled(4, 1, 1);
    
 	DrawUnitCube();
    
 	glPopMatrix();
    
  
    
 	glPopMatrix();
    
 	glPopMatrix();
    
 	glPopMatrix();
    
 	glPopMatrix();
    
 	glPopMatrix();
    
 	glPopMatrix();
    
 	gluDeleteQuadric(quad_obj);//销毁二次方程对象,释放内存
    
 }
    
  
    
 void CSphereView::DrawUnitCube()
    
 {
    
 	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    
 	for (int i = 0; i < 6; i++) {
    
 		glBegin(GL_QUADS);
    
 		int v0 = face[i * 4 + 0];
    
 		int v1 = face[i * 4 + 1];
    
 		int v2 = face[i * 4 + 2];
    
 		int v3 = face[i * 4 + 3];
    
 		glVertex3f(vert[v0 * 3 + 0], vert[v0 * 3 + 1], vert[v0 * 3 + 2]);
    
 		glVertex3f(vert[v1 * 3 + 0], vert[v1 * 3 + 1], vert[v1 * 3 + 2]);
    
 		glVertex3f(vert[v2 * 3 + 0], vert[v2 * 3 + 1], vert[v2 * 3 + 2]);
    
 		glVertex3f(vert[v3 * 3 + 0], vert[v3 * 3 + 1], vert[v3 * 3 + 2]);
    
 		glEnd();
    
 	}
    
 }

运行程序,能够显示机械臂和旋转关节。

复制代码
 typedef struct ArmDegreeStruct

    
 {
    
 	int xy = 0;
    
 	int yz = 0;
    
 	int xz = 0;
    
 } ArmDegree;
    
 ArmDegree armsDegree[3]; //to store degrees of arms
    
 GLdouble fovy = 100;

根据作业要求完成键盘123选择对应关节。SphereView.cpp所定义的结构体可知, 各关节的角度通过ArmsDegree数组的形式来表示, 因此需要通过调整ArmsDegree数组中的相关变量值来控制机械臂的旋转, 即只需修改ArmsDegree数组中的相关变量值即可完成控制。

首先,在代码库SphereView.h中定义一个变量用于存储当前被选中的人体骨骼关节。该操作流程将通过键盘选择对应的人体骨骼关节来进行操作。

复制代码
    int selectNum = 1;

为了避免因selectNum变量未被正确初始化而导致访问ArmsDegree[]数组时出现越界错误,为此采取的措施是将selectNum在初始化过程中设定为1。

因为存在三个序号,所以将selectNum的1,2,3值分别储存为对应的关节。

我们在程序的OnKeyDown方法中添加相应的键位:

复制代码
 switch(nChar)

    
 {
    
 case '1':
    
 		selectedNum = 1;
    
 		break;
    
 	case '2':
    
 		selectedNum = 2;
    
 		break;
    
 	case '3':
    
 		selectedNum = 3;
    
 		break;
    
 }

随后对选定的关节设定着色处理。在该处调用glColor3f函数来设定各关节的颜色参数。首先,在该处调用glColor3f函数来设定各关节的颜色参数;接着,在图形相关的Display函数中查找并获取对应的关节信息。

在这里需要注意的是,在绘制机械臂颜色时应使用glColor3f函数将其设置为白色以避免显示默认红色

复制代码
 //the first joint

    
 	if (selectedNum == 1) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	gluSphere(quad_obj, 1.0f, 20, 20);
    
  
    
 	//the first degree
    
 	glRotated(armsDegree[0].xy, 0, 0, 1);
    
 	glRotated(armsDegree[0].yz, 1, 0, 0);
    
 	glRotated(armsDegree[0].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the first arm
    
 	glPushMatrix();
    
 	glColor3f(1, 1, 1);
    
 	glTranslated(6, 0, 0);
    
 	glScaled(10, 2, 2);
    
 	DrawUnitCube();
    
 	glPopMatrix();
    
  
    
 	//draw the second joint
    
 	glTranslated(11.8, 0, 0);
    
 	glPushMatrix();
    
 	if (selectedNum == 2) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	gluSphere(quad_obj, 0.8f, 20, 20);
    
  
    
 	//the second degree
    
 	
    
 	glRotated(armsDegree[1].xy, 0, 0, 1);
    
 	glRotated(armsDegree[1].yz, 1, 0, 0);
    
 	glRotated(armsDegree[1].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the second arm
    
 	glColor3f(1, 1, 1);
    
 	glPushMatrix();
    
 	glTranslated(4.8, 0, 0);
    
 	glScaled(8, 1.5, 1.5);
    
 	DrawUnitCube();
    
 	glPopMatrix();
    
  
    
 	//draw the third joint
    
 	if (selectedNum == 3) { glColor3f(1, 0, 0); }
    
 	else { glColor3f(1, 1, 1); }
    
 	glTranslated(9.4, 0, 0);
    
 	glPushMatrix();
    
 	gluSphere(quad_obj, 0.6f, 20, 20);
    
  
    
 	//the third degree
    
 	glRotated(armsDegree[2].xy, 0, 0, 1);
    
 	glRotated(armsDegree[2].yz, 1, 0, 0);
    
 	glRotated(armsDegree[2].xz, 0, 0, 1);
    
 	glPushMatrix();
    
  
    
 	//draw the third arm
    
 	glColor3f(1, 1, 1);
    
 	glPushMatrix();
    
 	glTranslated(2.6, 0, 0);
    
 	glScaled(4, 1, 1);
    
 	DrawUnitCube();
    
 	glPopMatrix();

随后我们执行相应的机械臂旋转变换操作。由于已保存好相关关节信息,则只需更新ArmsDegree数组中的旋转变换数据即可。在OnKeyDown事件处理函数中增加以下代码:

复制代码
     case 'W':

    
 		armsDegree[selectedNum - 1].xy += 2;
    
 		break;
    
 	case 'S':
    
 		armsDegree[selectedNum - 1].xy -= 2;
    
 		break;
    
 	case 'A':
    
 		armsDegree[selectedNum - 1].xz += 2;
    
 		break;
    
 	case 'D':
    
 		armsDegree[selectedNum - 1].xz -= 2;
    
 		break;
    
 	case 'Q':
    
 		armsDegree[selectedNum - 1].yz += 2;
    
 		break;
    
 	case 'E':
    
 		armsDegree[selectedNum - 1].yz -= 2;
    
 		break;

这样作业2就实现完成了。

全部评论 (0)

还没有任何评论哟~