Иллюстрированный самоучитель по Visual Studio .NET

Как создать сферу

Для того чтобы из существующей заготовки – икосаэдра из двадцати граней – создать сферу, круглую, блестящую и без изъянов, нужно осуществить предельный переход, как в матанализе, бесконечно увеличивая число треугольников при бесконечном уменьшении их размеров. В дискретном мире нет места предельным переходам, поэтому вместо бесконечного деления надо ограничиться каким-то конечным числом и начать делить каждый из двадцати треугольников икосаэдра на все более мелкие правильные треугольники.

Вычисление нормали при этом упрощается, так как при приближении к шару нормаль в каждой вершине треугольника приближается к нормали поверхности шара. А последняя равна нормированному вектору радиуса текущей точки. Алгоритм деления проиллюстрируем рисунком (рис. 6.3).

Иллюстрированный самоучитель по Visual Studio .NET › Графика OpenGL › Как создать сферу
Рис. 6.3. Деление треугольника икосаэдра

Треугольник с вершинами V1, V2 и V3 разбивается на четыре треугольника: (V1,V12,V31), (V2,V23,V12), (V3,V32,V23) и (V12.V23.V31). После этого промежуточные точки деления надо посадить на поверхность шара, то есть изменить их координаты так, чтобы концы векторов (V12, V23 и V31) дотянулись до поверхности шара. Для этого достаточно нормировать векторы с помощью уже существующей процедуры Scale. Она впоследствии будет использована как для масштабирования нормали, так и для нормировки координат вершин новых треугольников. Но сейчас мы будем вычислять нормаль приближенно. Введем еще две вспомогательные функции:

//=== Команды OpenGL для изображения одного треугольника
void setTria (double *v1, double *v2, double *v3)
{
//====== Нормаль и вершина задаются одним вектором
glNormal3dv(vl);
glVertex3dv(vl);
glNormalSdv (v2);
glVertex3dv(v2);
glNormal3dv(v3);
glVertex3dv(v3);
glEnd();
}
//====== Генерация внутренних треугольников
void Split(double *v1, double *v2, double *v3)
{
//====== Промежуточные вершины
double v12[3], v23[3], v31[3);
for (int l=0; l< 3; i++) {
//======Можно не делить пополам,
//====== так как будем нормировать
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31 [i] = v3[i]+v1 [i];
}
//====== Нормируем три новые вершины
Scale(v12);
Scale(v23);
Scale(v31); //====== и рисуем четыре треугольника
setTria(v1, v12, v31);
setTria (v2, v23, v12);
setTria(v3, v31, v23);
setTria(v12,v23, v31);
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.