TP-rendu/TP3/robot.c
2023-06-22 20:30:57 +02:00

356 lines
8.7 KiB
C

#include <stdlib.h>
#include <stdio.h>
// for mac osx
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
// only for windows
#ifdef _WIN32
#include <windows.h>
#endif
// for windows and linux
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <math.h>
// Global variables to animate the robotic arm
int Angle1 = 45;
int Angle2 = 45;
// Global variables to rotate the arm as a whole
int RobotAngleX = 0;
int RobotAngleY = -20;
float pincer = 0.5;
//*************************************************************************
// Function that draws a reference system
//*************************************************************************
void DrawReferenceSystem()
{
//**********************************
// set the line width to 3.0
//**********************************
glLineWidth(3);
//**********************************
// Draw three lines along the x, y, z axis to represent the reference system
// Use red for the x-axis, green for the y-axis and blue for the z-axis
//**********************************
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 1);
glEnd();
//**********************************
// reset the drawing color to white
//**********************************
glColor3f(1, 1, 1);
//**********************************
// reset the line width to 1.0
//**********************************
glLineWidth(1);
}
//*************************************************************************
// Function that draws a single joint of the robotic arm
//*************************************************************************
void DrawJoint()
{
// first draw the reference system
DrawReferenceSystem();
// Draw the joint as a parallelepiped (a cube scaled on the y-axis)
// the bottom face of the cube must be on the xz plane
//**********************************
// draw the parallelepiped
//**********************************
glPushMatrix();
glTranslatef(0, 1, 0);
glScalef(1, 2, 1);
glutWireCube(1);
glPopMatrix();
}
// Function that draws the robot as three parallelepipeds
void DrawRobot()
{
//**********************************
// It's better to work on a local reference system...
//**********************************
glPushMatrix();
// draw the first joint
DrawJoint();
// Draw the other joints
// every joint must be placed on top of the previous one
// and rotated according to the relevant Angle
//**********************************
// the second joint
//**********************************
glTranslatef(0, 2, 0);
glRotatef(Angle1, 0, 0, 1);
DrawJoint();
//**********************************
// the third joint
//**********************************
glTranslatef(0, 2, 0);
glRotatef(Angle2, 0, 0, 1);
DrawJoint();
//**********************************
// the pincer's base
//**********************************
glTranslatef(0, 2, 0);
DrawReferenceSystem();
glPushMatrix();
glTranslatef(0, 0.125, 0);
glScalef(1, 0.25, 0.25);
glutWireCube(1);
glPopMatrix();
glTranslatef(0, 0.25, 0);
DrawReferenceSystem();
// pincer left
glPushMatrix();
glTranslatef(pincer, 0.5, 0);
glScalef(0.25, 1, 0.25);
glutWireCube(1);
glPopMatrix();
// picer right
glPushMatrix();
glTranslatef(-pincer, 0.5, 0);
glScalef(0.25, 1, 0.25);
glutWireCube(1);
glPopMatrix();
//**********************************
// "Release" the copy of the current MODELVIEW matrix
//**********************************
glPopMatrix();
}
//*************************************************************************
// display callback
//*************************************************************************
void display(void)
{
// clear the window
glClear(GL_COLOR_BUFFER_BIT);
// working with the GL_MODELVIEW Matrix
glMatrixMode(GL_MODELVIEW);
//**********************************
// we work on a copy of the current MODELVIEW matrix, hence we need to...
//**********************************
glPushMatrix();
//**********************************
// Rotate the robot around the x-axis and y-axis according to the relevant angles
//**********************************
glRotatef(RobotAngleX, 1, 0, 0);
glRotatef(RobotAngleY, 0, 1, 0);
// draw the robot
DrawRobot();
//**********************************
// not anymore on a local reference system
//**********************************
glPopMatrix();
// flush drawing routines to the window
glutSwapBuffers();
}
//*************************************************************************
// Special keys callback
//*************************************************************************
void arrows(int key, int x, int y)
{
//**********************************
// Manage the update of RobotAngleX and RobotAngleY with the arrow keys
//**********************************
switch (key)
{
case GLUT_KEY_LEFT:
RobotAngleY += 5;
break;
case GLUT_KEY_RIGHT:
RobotAngleY -= 5;
break;
case GLUT_KEY_UP:
RobotAngleX += 5;
break;
case GLUT_KEY_DOWN:
RobotAngleX -= 5;
break;
default:
break;
}
glutPostRedisplay();
}
//*************************************************************************
// Keyboard callback
//*************************************************************************
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
case 27:
exit(0);
break;
//**********************************
// Manage the update of Angle1 with the key 'a' and 'z'
//**********************************
case 'a':
Angle1 += 5;
break;
case 'z':
Angle1 -= 5;
break;
//**********************************
// Manage the update of Angle2 with the key 'e' and 'r'
//**********************************
case 'e':
Angle2 += 5;
break;
case 'r':
Angle2 -= 5;
break;
//**********************************
// Manage the pincer
//**********************************
case 'o':
pincer += 0.01;
break;
case 'l':
pincer -= 0.01;
break;
default:
break;
}
if (pincer >= 0.5)
{
pincer = 0.5;
}
else if (pincer <= 0.125)
{
pincer = 0.125;
}
glutPostRedisplay();
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, 1.0, 1.0, 100.0);
glShadeModel(GL_FLAT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Place the camera
gluLookAt(-6, 5, -6, 0, 0, 2, 0, 1, 0);
}
//*************************************************************************
// Function called every time the main window is resized
//*************************************************************************
void reshape(int width, int height)
{
// define the viewport transformation;
glViewport(0, 0, width, height);
if (width < height)
glViewport(0, (height - width) / 2, width, width);
else
glViewport((width - height) / 2, 0, height, height);
}
//*************************************************************************
// Prints out how to use the keyboard
//*************************************************************************
void usage()
{
printf("\n*******\n");
printf("Arrows key: rotate the whole robot\n");
printf("[a][z] : move the second joint of the arm\n");
printf("[e][r] : move the third joint of the arm\n");
printf("[esc] : terminate\n");
printf("*******\n");
}
//////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
//**********************************
// Register the keyboard function
//**********************************
glutKeyboardFunc(keyboard);
//**********************************
// Register the special key function
//**********************************
glutSpecialFunc(arrows);
// just print the help
usage();
glutMainLoop();
return EXIT_SUCCESS;
}
//////////////////////////////////////////////////////////////