我编写了以下代码:
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#define WIDTH 400
#define HEIGTH 400
#define ORIGIN_X 50
#define ORIGIN_Y 50
#define move(x,y) glTranslatef(x, y, 0.0f);
#define enlarge(y) glScalef(1, y, 1);
#define rotateX(angle) glRotatef(angle, 1,0,0);
#define rotateY(angle) glRotatef(angle, 0,1,0);
#define rotateZ(angle) glRotatef(angle, 0,0,1);
// Variables que definen la rotación del brazo entero (de hombro a mano)
static GLfloat shoulder_Xangle, shoulder_Yangle, shoulder_Zangle;
// Variables que definen sólo la rotación del antebrazo (de codo a mano)
static GLfloat elbow_Xangle, elbow_Yangle, elbow_Zangle;
void keyboardHandler(unsigned char key, int x, int y ){
switch(key){
case 'q': shoulder_Zangle++; break;
case 'e': shoulder_Zangle--; break;
case 'a': shoulder_Yangle++; break;
case 'd': shoulder_Yangle--; break;
case 'w': shoulder_Xangle++; break;
case 's': shoulder_Xangle--; break;
case 'r': elbow_Zangle++; break;
case 'y': elbow_Zangle--; break;
case 'f': elbow_Yangle++; break;
case 'h': elbow_Yangle--; break;
case 't': elbow_Xangle++; break;
case 'g': elbow_Xangle--; break;
default: break;
}
glutPostRedisplay(); // Avisa que la ventana ha de refrescarse
}
void init() {
glutKeyboardFunc(keyboardHandler); // Asociar handler a eventos procedentes del teclado
glClearColor(0.0,0.0,0.0,0.0); // Fijar el color por defecto a negro en el formato RGBA
}
void rotate(GLfloat Xangle, GLfloat Yangle, GLfloat Zangle) {
rotateX(Xangle); // Rotar Xangle grados sobre el eje X
rotateY(Yangle); // Rotar Yangle grados sobre el eje Y
rotateZ(Zangle); // Rotar Zangle grados sobre el eje Z
}
void draw_sphere(GLdouble radius) {
GLint slices = 360;
GLint stacks = 360;
glutWireSphere(radius, slices, stacks);
}
void draw_cube() {
glBegin(GL_QUADS);
glColor3f ( 0.0, 0.7, 0.1); // Parte anterior: verde
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glColor3f ( 1.0, 0.0, 0.0); // Parte posterior: rojo
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glColor3f ( 1.0, 1.0, 1.0); // Resto: blanco
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, 0.5);
glVertex3f( 0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f( 0.5, -0.5, 0.5);
glVertex3f( 0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glEnd();
}
void draw_shoulder() { draw_sphere(0.5); }
void draw_elbow() {
move(0, -3.0) // 3) Colocar en su posición final
rotate(elbow_Xangle, elbow_Yangle, elbow_Zangle); // 2) Rotamiento del codo
draw_sphere(0.5); // 1) Dibujar 1 esfera (codo)
}
void draw_arm() {
move(0.0, -1.5); // 3) Colocar en su posición final
enlarge(2.0); // 2) Escalar el brazo
draw_cube(); // 1) Dibujar 1 cubo (brazo)
}
void draw_forearm() {
move(0.0, -3.0); // 5) Colocar en su posición final
rotate(elbow_Xangle, elbow_Yangle, elbow_Zangle); // 4) Rotamiento del codo
move(0.0, -1.5); // 3) Mover hacia abajo para que el radio de rotación = tamaño codo
enlarge(2.0); // 2) Escalar el antebrazo
draw_cube(); // 1) Dibujar 1 cubo (antebrazo)
}
void draw_hand() {
move(0, -3.0); // 4) Colocar en su posición final
rotate(elbow_Xangle, elbow_Yangle, elbow_Zangle); // 3) Rotamiento del codo
move(0.0, -2.5) // 2) Mover hacia abajo el tamaño del codo+antebrazo = (1.0+2.0)-0.5
rotateX(90); // 1) Poner la mano en su sitio
glutSolidCone(0.5, 1.5, 360, 360);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Borrado del FrameBuffer
glEnable(GL_DEPTH_TEST);
glLoadIdentity(); // Cargar la matriz identidad en la matriz de proyección
rotate(shoulder_Xangle, shoulder_Yangle, shoulder_Zangle); // Movimiento del hombro
draw_shoulder(); // Dibujar el hombro
glLoadIdentity();
rotate(shoulder_Xangle, shoulder_Yangle, shoulder_Zangle); // Movimiento del hombro
draw_arm(); // Dibujar el brazo
glLoadIdentity();
rotate(shoulder_Xangle, shoulder_Yangle, shoulder_Zangle); // Movimiento del hombro
draw_elbow(); // Dibujar el codo
glLoadIdentity();
rotate(shoulder_Xangle, shoulder_Yangle, shoulder_Zangle); // Movimiento del hombro
draw_forearm(); // Dibujar el antebrazo
glLoadIdentity();
rotate(shoulder_Xangle, shoulder_Yangle, shoulder_Zangle); // Movimiento del hombro
draw_hand(); // Dibujar la mano
// Forzar renderizado
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION); // Activar las modificaciones en la cámara
glLoadIdentity();
glOrtho(-8, 8, -12, 4, -8, 8);
glMatrixMode(GL_MODELVIEW); // Activar las modificaciones en el modelo
}
int main(int argc, char** argv) {
glutInit(&argc, argv); // Cargar el teclado y el ráton
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Búffer doble, con color RGB y profundidad
glutInitWindowSize(WIDTH, HEIGTH); // Tamaño de la ventana
glutInitWindowPosition(ORIGIN_X, ORIGIN_Y); // Posición del extremo superior-izquierdo de la ventana
glutCreateWindow("Brazo Articulado"); // Crear la ventana
init();
glutDisplayFunc(display); // Activar la función de pintado
glutReshapeFunc(reshape); // Activar la función de escalado
glutMainLoop(); // Arrancar el bucle de OpenGL
return 0;
}
基本上,我的手臂由肩、臂、肘、前臂和手组成。当肩部旋转时,所有这些组件也必须旋转。但是,当肘部旋转时,只有肘部、前臂和手是旋转的。
有人告诉我,只需添加两个“旋转”句子(一个用于肩膀,一个用于肘部),就可以实现相同的功能,而不是像我对每个组件所做的那样。
你知道怎么做吗?