Строим икосаэдр
Для иллюстрации работы с массивами вершин создадим более сложный объект – икосаэдр. Это такой десятистенный дом с острой пятиугольной крышей и таким же полом, но углы пола смещены (повернуты) на π/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 ();
}
