Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Chast_II_Osn_progr_trekhmernoy_grafiki.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.83 Mб
Скачать

3.2 Модель манипулятора робота

Манипулятор робота на экране изображается в виде нескольких каркасных параллелепипедов (по одному для каждого сегмента манипулятора – "плечо", "локоть", "кисть", "пальцы"). Предполагается, что в местах соединения сегментов расположены шарниры и сегменты могут вращаться вокруг них. На рис. 2.2 и рис. 2.3 показаны манипуляторы с разным количеством сегментов.

Рис. 2.2. Двухсегментный манипулятор.

Рис. 2.3. Манипулятор из 10 сегментов (плечо, локоть и 4 пальца).

Перед рисованием каждого сегмента надо выполнить модельное преобразование, обеспечивающее корректную ориентацию сегмента. При рисовании параллелепипеда его центр располагается в начале модельной системы координат, поэтому предварительно надо сместить модельную систему координат на половину длины сегмента. Если этого не сделать, то сегмент будет вращаться вокруг своего центра, а не вокруг шарнира.

После вызова glTranslated(), который задает положение шарнира, надо вызвать glRotated() для поворота сегмента. После этого надо выполнить перенос в обратном направлении для правильного позиционирования центра сегмента. В целом, для рисования одного сегмента надо вызвать следующие функции:

glTranslatef( -1.0, 0.0, 0.0 );

glRotatef( (float)shoulder_angle, 0.0, 0.0, 1.0 );

glTranslatef( 1.0, 0.0, 0.0 );

auxWireBox( 2.0, 0.4, 1.0 );

Для рисования второго сегмента надо переместить модельную систему координат в позицию второго шарнира. Т.к. координатная система уже была повернута, то ось X направлена в направлении первого сегмента. Следовательно, для переноса модельной системы координат в точку второго шарнира надо произвести перенос вдоль оси X. После этого можно нарисовать второй сегмент (функциями, аналогичными использованным для рисования первого сегмента):

glTranslatef( 1.0, 0.0, 0.0 );

glRotatef( (float)elbow_angle, 0.0, 0.0, 1.0 );

glTranslatef( 1.0, 0.0, 0.0 );

auxWireBox( 2.0, 0.4, 1.0 );

Описанную процедуру можно продолжать повторять, чтобы нарисовать все сегменты манипулятора (плечо, локоть, кисть, пальцы). Рисование двух сегментов манипулятора с двумя степенями свободы показано в программе 2.3. Поворот сегментов осуществляется с помощью клавиш курсора.

#include <windows.h>

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

void CALLBACK resize( int width, int height );

void CALLBACK display();

void CALLBACK elbowAdd();

void CALLBACK elbowSubtract();

void CALLBACK shoulderSubtract();

void CALLBACK shoulderAdd();

// Текущие углы поворота плеча и локтя

int shoulder = 0, elbow = 0;

void main()

{

  // Создание экранного окна

  auxInitDisplayMode( AUX_RGBA | AUX_DEPTH | AUX_DOUBLE );

  auxInitPosition( 50, 10, 400, 400);

  auxInitWindow( "Лекция 2, Программа 2.3" );

  // Включение ряда параметров OpenGL

  glEnable( GL_ALPHA_TEST );

  glEnable( GL_DEPTH_TEST );

  glEnable( GL_COLOR_MATERIAL );

  glEnable( GL_BLEND );

  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

  glEnable( GL_LIGHTING );

  // Включение максимального рассеянного освещения

  float ambient[4] = { 1.0, 1.0, 1.0, 1 };

  glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );

  // Регистрация обработчиков событий

  auxReshapeFunc( resize );

  auxKeyFunc( AUX_LEFT, shoulderSubtract );

  auxKeyFunc( AUX_RIGHT, shoulderAdd );

  auxKeyFunc( AUX_UP, elbowAdd );

  auxKeyFunc( AUX_DOWN, elbowSubtract );

  // Вход в главный цикл GLAUX

  auxMainLoop( display );

}

void CALLBACK resize( int width, int height )

{

  glViewport( 0, 0, width, height );

  glMatrixMode( GL_PROJECTION );

  glLoadIdentity();

  gluPerspective( 60.0, (float)width/(float)height, 1.0, 20.0 );

  gluLookAt( 0,0,10, 0,0,0, 0,1,0 );

  glMatrixMode( GL_MODELVIEW );

  glLoadIdentity();

}

void CALLBACK display()

{

  // Очистка буфера кадра

  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  glColor3f( 1.0, 1.0, 1.0 );

  glPushMatrix();

    glTranslatef( -1.0, 0.0, 0.0 );

    glRotatef( (float)shoulder, 0.0, 0.0, 1.0 );

    glTranslatef( 1.0, 0.0, 0.0 );

    auxWireBox( 2.0, 0.4, 1.0 ); // плечо

    glTranslatef( 1.0, 0.0, 0.0 );

    glRotatef( (float)elbow, 0.0, 0.0, 1.0 );

    glTranslatef( 1.0, 0.0, 0.0 );

    auxWireBox( 2.0, 0.4, 1.0 ); // локоть

  glPopMatrix();

  // Копирование содержимого буфера кадра на экран

  glFlush();

  auxSwapBuffers();

}

void CALLBACK elbowAdd()

{

  elbow = (elbow + 5) % 360;

}

void CALLBACK elbowSubtract()

{

  elbow = (elbow - 5) % 360;

}

void CALLBACK shoulderAdd()

{

  shoulder = (shoulder + 5) % 360;

}

void CALLBACK shoulderSubtract()

{

  shoulder = (shoulder - 5) % 360;

}

Программа 2.3. Модель манипулятора робота.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]