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)
还没有任何评论哟~
