Строим икосаэдр
Для иллюстрации работы с массивами вершин создадим более сложный объект – икосаэдр. Это такой десятистенный дом с острой пятиугольной крышей и таким же полом, но углы пола смещены (повернуты) на π/5 относительно углов потолка.
Икосаэдр имеет 20 треугольных граней и 12 вершин (1 + 5 на потолке и 1 + 5 на полу). Благодаря своей правильности он может быть задан с помощью всего лишь двух чисел, которые лучше вычислить один раз и запомнить. Этими числами является косинус и синус угла в три пятых окружности, то есть:
static double //====== atan(l.) – это пи/4 angle = 3. * atan(1.)/2.5, //====== 2 характерные точки V = cos(angle), W = sin(angle);
Этот код мы вставим внутрь функции рисования, чтобы не плодить глобальные переменные и не нарываться на конфликты имен. Вот новая версия функции DrawScene:
void DrawScene() { static double //====== 2 характерные точки angle = 3. * atan(l.)/2.5, V = cos(angle), W = sin(angle), //=== 20 граней икосаэдра, заданные индексами вершин static GLuint id[20][3] =
(0.1, 4), (8.1.10), (7.3.10), (6.10.1), |
(0.4, 9), (8.10.3), (7.10.6), (9.11.0), |
(9.4, 5), (5.8, 3), (7.6.11), (9.2.11), |
(4.8, 5), (5.3, 2), (11.6.0), (9.5, 2), |
(4.1.8), (2.3.7), (0.6.1), (7.11.2) |
//====== Начинаем формировать список команд glNewList (1,GL_COMPILE); //====== Выбираем текущий цвет рисования glColor3d (1., 0.4, 1.); glBegin (GLJTRIANGLES); for (int i = 0; i < 20; i++) { //====== Грубый подход к вычислению нормалей glNormal3dv(v[id[i] [0] ]); glVertex3dv(v[id[i] [0] ]); glNormal3dv(v[id[i] [1] ]); glVertex3dv(v[id[i] [1] ]); glNormal3dv(v[id[i] [2] ]); glVertex3dv(v[id[i] [2] ]); } glEnd(); //====== Конец списка команд glEndList (); }