This section discusses a program that creates an articulated robot arm with two or more segments. The arm should be connected with pivot points at the shoulder, elbow, or other joints. Figure 3-22 shows a single joint of such an arm.
![[IMAGE]](figures/robot.gif)
Figure 3-22 : A Robot Arm
You can use a scaled box as a segment of the robot arm, but first you must call the appropriate modeling transformations to orient each segment. Since the origin of the local coordinate system is initially at the center of the box, you need to move the local coordinate system to one edge of the box. Otherwise, the box rotates about its center rather than the pivot point.
After you call glTranslate*() to establish the pivot point and glRotate*() to pivot the box, translate back to the center of the box and then draw the box. Here's what your code might look like for this first segment of the arm (the entire program is shown in Example 3-7 ):
glTranslatef (-1.0, 0.0, 0.0); glRotatef ((GLfloat) shoulder_angle, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); auxWireBox(2.0, 0.4, 1.0);
To build a second segment, you need to move the local coordinate system to the next pivot point. Since the coordinate system has previously been rotated, the x-axis is already oriented along the length of the rotated arm. Therefore, translating along the x-axis moves the local coordinate system to the next pivot point. Once it's at that pivot point, you can use the same code to draw the second segment as you used for the first one. This can be continued for an indefinite number of segments (shoulder, elbow, wrist, fingers).
glTranslatef (1.0, 0.0, 0.0); glRotatef ((GLfloat) elbow_angle, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); auxWireBox(2.0, 0.4, 1.0);
Example 3-7 : A Robot Arm: robot.c
#include <GL/gl.h>
#include <GL/glu.h>
#include "aux.h"
static int shoulder = 0, elbow = 0;
void elbowAdd (void)
{
elbow = (elbow + 5) % 360;
}
void elbowSubtract (void)
{
elbow = (elbow - 5) % 360;
}
void shoulderAdd (void)
{
shoulder = (shoulder + 5) % 360;
}
void shoulderSubtract (void)
{
shoulder = (shoulder - 5) % 360;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
glTranslatef (-1.0, 0.0, 0.0);
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
auxWireBox(2.0, 0.4, 1.0); /* shoulder */
glTranslatef (1.0, 0.0, 0.0);
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);
auxWireBox(2.0, 0.4, 1.0); /* elbow */
glPopMatrix();
glFlush();
}
void myinit (void)
{
glShadeModel (GL_FLAT);
}
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);
auxInitPosition (0, 0, 400, 400);
auxInitWindow (argv[0]);
myinit ();
auxKeyFunc (AUX_LEFT, shoulderSubtract);
auxKeyFunc (AUX_RIGHT, shoulderAdd);
auxKeyFunc (AUX_UP, elbowAdd);
auxKeyFunc (AUX_DOWN, elbowSubtract);
auxReshapeFunc (myReshape);
auxMainLoop(display);
}
Try This
Modify
Example 3-7
to add additional segments onto the robot arm.
Modify Example 3-7 to add additional segments at the same position. For example, give the robot arm several "fingers" at the wrist, as shown in Figure 3-23 . Hint: Use glPushMatrix() and glPopMatrix() to save and restore the position and orientation of the coordinate system at the wrist. If you're going to draw fingers at the wrist, you need to save the current matrix prior to positioning each finger and restore the current matrix after each finger is drawn.
![[IMAGE]](figures/ch03-4.gif)
Figure 3-23 : Robot Arm with Fingers
OpenGL Programming Guide