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


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


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

Рис. 6.3. Деление треугольника икосаэдра

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

//=== Команды OpenGL для изображения одного треугольника

void setTria(double *vl, double *v2, double *v3)

{

//====== Нормаль и вершина задаются одним вектором

glNormal3dv(vl);

glVertex3dv(vl);

glNormalSdv (v2);

glVertex3dv(v2);

glNormal3dv(v3);

glVertex3dv(v3);

glEnd() ;

}

//====== Генерация внутренних треугольников

void Split(double *vl, double *v2, double *v3)

{

//====== Промежуточные вершины

double v!2[3], v23[3], v31[3);

for (int l=0; l< 3; i++) {

//====== Можно не делить пополам,

//====== так как будем нормировать

v12[i] = vl[i]+v2[i];



Начало  Назад  Вперед