М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 21
Текст из файла (страница 21)
Определение векторов нормали к поверхности 0СГ1овС б1(3], б2[3], поги(З], Го. Ц = В; 1 < 3; )++) ( б1[1] = чс[аса[стпбтсев(т][в]][]] — хоота[стоб[сев(!][ ц ][1]; б2[)] = чбвса [ с!пб[сев [(] [ Ц ] [1] — чбата[Стпб[сев[]][2]][1]; поте<Гевар<об(б1, б2, посв); а1иогва13[ч(поте); Процедура погмсгоезргоб() вычисляет нормализованное векторное произведе- ние двух векторов, как показано в листинге 2.18. Листинг 2.18.
Вычисление нормализованного векторного произведения двух векторов чо[б погва1!се(Г[оаС ч(3]) ( аСГ]овС б = вйгС(ч [О] "ч [0] -ч(ц *ч [ц+ч [2]*ч [2] ): (б == 0.0) ( еггог("вектор нулевой дпнны")! гесогп; ч(0) /= б; ч[ Ц /= б; ч(2] /= б; ) чотб погвсговвргоб( [1овС ч1[3\, (1оаС ч1(3], г1оаС ооС (3]) ( оиС[0] =ч1[ц'ч1[2] — ч[(2] "чс(ц; ой! [ц =ч1(2] 'ч2 [О] — чс[0] 'ч2 [2]; бог [2) =ч1(0] *ч2 (ц — ч1[ц *ч2 [О]; погав1тсе(ооС); Если икосаздр используется для аппроксимации закрашенной сферы, вы можете захотеть определить векторы нормалей, перпендикулярные к истинной поверхности сферы, а не к граням. Для сферы получение векторов нормалей делается просто: по любой точке в направлении от центра к соответствующей вершине.
Так как информация о вершинах определена для икосаздра с единичным радиусом, векторы нормалей такие же. В следующем коде сглаженная затененная сфера аппроксимируется икосаэдром (полагаем, что освещение включено, как описано в главе 5): а[Вез!о(0С та[аис[ЕЗ): Гог (! = О; ! < 2О; !++) ( а1иогвэ[ЗГч(ахов!а[Стоб[сев(т][0]](В]); асуегеехЗ(ч(ачбвСв[Стпбтсев( ц [0]][9]); Несколько советов по построению полигонапьных моделей поверхностей 93 В(иогва13(ч(йчдаСа[1(пд!сея[!][1]][О]): В]чеггехЗ(ч(йчдага[1!пд!сея[(][1]][0]): В(ногае(3(ч(йчдага[1!пд(сея[(] 12]][О]); Е1чеггехЗ(ч(йчдага[ 1!пд(сея[(][2]][0]); ] 31Епд() ', Повышение качества модели Двадпатигранная аппроксимация сферы не выглядит хорошо, поэтому обратимся к простому способу увеличения точности аппроксимации.
Представьте икосаэдр вписанным в сферу и разделенным на треугольники, как показано на рис. 2.17. Поместим на поверхность новые вершины путем нормализации (разделим их на коэффициент для получения единичной длины). Этот процесс разбиения повторяется до достижения необходимой точности. Три объекта на рис. 2.17 состоят из 20, 80 и 820 аппроксимирующих треугольников. -.163...
Рис. 2.17. Разукрупненне с целью улучшения полнгональной аппроксимации поверхности Листинг 2.19 демонстрирует получение из 20-гранного икосаздра 80-грашюй поверхности. Листинг 2.19. Разбиение граней на треугольники чо(д дгангг!апх1е((1оаг 'ч1, Моет *чг, (1еаг *чЗ) ( 61аек!п(66 та[ЯМ6ЕЕ5); 61ногва13(ч(ч1); 61уеггехЗ(ч(ч1); 61Могва13(ч(чг); 61НеггехЗ(ч(чг). 61ногва13 Гч(ч3); К1НеггехЗ(ч(чЗ); В1Епд(); ) ЧЕ1О ьцьд!ч!де((1оа[ *ч1, (1оаг 'ч2, (1оа1 'чЗ) ( 6Е(1оат ч12[3], ч23[3], ч)1[3]; 66!пг (; Гог (! =О; ! < 3; (в+) ( ч12[!1 = (ч1[!]+ч2[(])/г.о; ч23[з1 = (ч2[!]вч)[(])/2,0; продолжение ег 94 Глава 2 ч Управление состоянием и рисование геометрических объектов Листинг 2.19 (продолжение) ч31[[] = (чЗ[[]+ч1[[])/2.0; погва[[се(ч12); погва[[се(ч23); погва[ссе(ч31); бгаитг]апа[е(ч1, ч12, ч31); бгаи(г]апк1е(ч2, ч23, ч12): бгаи(г[апк[е(чЗ, ч31, ч23); бгаи(г]апя[е(ч12, ч23, ч31); аког (! = 0; ! < 20: [++) ( ацьб[ч[бе(ачбаса[с!пб[сеа[[][0]][0], ачбата[С[пб]се![]][1]][0), ачбата[С[по]се»[]][2]][0]): ) Теперь выполним рекурсивное разбиение треугольников до требуемой точности.
Для чего в листинг 2.19 внесем небольшие изменения, и зто будет уже листинг 2.20. Если значение «глубины» (вложенности) равно О, разбиение не выполняется и треугольники рисуются «как есть». Если глубина равна 1, разбиение выполняется один раз и т.
д. Листинг 2.20. Рекурсивное разбиение чо!б аоьб[ч]бе(тсоаС «чс, Ссра( *ч2, С[оаС чЗ, [опа берСП) ( ОСЕ[па! ч12[3], ч23[3], ч31[3]; ОС]пС ]; !! (берСП == 0) ( бгаи[г]эпе[е(ч1, ч2, чЗ); гесогп; сог (! = 0; !' < 3; ! н.) ( ч12[!] = (ч1[[]+ч2[]])(2 0; ч23[з] = (ч2[[]+чЗ[!])/2,0; ч31[[] = (чЗ[]]+ч1[!])/2.8; погва[[се(ч12); погва1[се(ч23): погвас]се(ч31); »ЬЬб[ч[бе(ч1, ч12, ч31, берто-1); »оЬб[ч[бе(ч2, ч23, ч12, берСП-1); аоьб[ч[бе(чЗ, ч31, ч23, берСП-1); ацьб!ч]бе(ч12, ч23, ч31, берта-1); Обобщенное разбиение Рассмотренная технология рекурсивного разбиения пригодится и для других ви дов поверхностей. Обычно рекурсия прекращается, если достигается заданн Несколько советов по попроенню полнгональных моделей поверхностей 95 глубина или выполняется некоторое условие на кривизну (сильно искривленные части поверхности выглядят лучше при большом разбиении).
Для нахождения более общего решения проблемы разбиения рассмотрим произ- вольную поверхность, определяелгую двумя параметрами, и]0] и и]1]. Допустим, имеется две функции: чгд б авгс(61(1оа! в[2], 6сг!Оаг чегсех(3], 6сг!Оа! погаэ![3]); (1оаг свГЧ(6ьг!оа! О[2]); При передаче и]] в качестве аргумента функции за г Г () возвращается соответствующая трехмерная вершина и вектор нормали (длиной 1). Если и~] передается функции с вгч(), вычисляется и возвращается кривизна поверхности в данной точке. (См.
учебник по дифференциальной геометрии для получения информации о вычислении кривизны.) Листинг 2.21. Обобщенное разбиение ча(б 5ОЬб]ч(бе((1оа! О1[2], г!Оас О2[2], Г!Ьа! вЗ[2], Г1оат со!о!с, !ППХ бер!Ь) ( 6!(!оаг ч1[3], ч2[3], чЗ[3], п1[3], п2[3], пЗ[3]; 6сг!Ьа! О12[2], О23[2], О32[2]; 6Е!и! !; (! (берса == вахберсь свгч(в2) < 5ОГ((О1, ч1, п1); 5вгг(О2, ч2, п2); 5вгг(ОЗ.
чз, пз); а!Век(п(6! РОЕт60Н); К!Но/на!Згч(П1); Б!Ногаа!Згч(П2); Х!Ногае!Згч(ПЗ); В!ЕПОО; ГЕ!ОГП; (свгч(О1) < сосо!с Йа свго(Г аа свгч(ОЗ) < св!ОГ!)) [ х!Нег!ехЗЕч(ч1); Х!Нег(ехзгч(ч2); Х!НегсехЗтч(чЗ); ) (ог (! = О; ! < 2; ]++) ( О12[5! = (О1[ч! + О2[!])/2.0; в23[5] = (О2[5! <ОЗ[(])/2.0; О31[!] = (ОЗ[З] +О1[(])/2.0; 5ОЬб/ч]бе(О1, О12, в31, 5ОЬбзч(бе(О2, О23, О12, 5ОЬб(ч(бе(ОЗ, О31, О23, 5ОЬб(ч(бе(О12, О23, О31 св!Ьг(, бер!Ь+1); свсогт, бер!Ь+1); св!О(Г, берть+1); св!Отг, берть+1) Листинг 2.21 показывает рекурсивную процедуру разбиения треугольника до тех пор, пока не достигается максимальная вложенность или максимальная кривизна в трех вершинах не станет меньше некоего предела.
Визуализация Прочитав эту главу, вы сможете: е Просматривать геометрическую модель в любом положении, осуществляя преобразования в трехмерном пространстве ° Управлять местоположением наблюдателя в трехмерном пространстве ° Удалять ненужные части модели из сцены ° работать с набором матриц, которые управляют изменениями модели, и проецировать модель на экран ° Осуществлять групповые трансформации для имитации сложных систем в движении, таких как солнечная система или рука робота ° Обращать результаты конвейера геометрической обработки Визуализация 97 В главе 2 было рассказано, как с помощью ОрепС1. строить геометрические модели для вывода на сцену.
Теперь нужно определиться, как расположить модели в сцене, н определить наиболее удачную точку ее обзора. Конечно, можно использовать и значения по умолчанию, но, скорее всего, вы захотите их изменить. Посмотрите на цветной рисунок 1. Программа, создавшая это изображение, содержала единственное геометрическое описание «строительного» блока, Каждый блок был тщательно позиционнрован в сцене: некоторые блоки были разбросаны ва полу, другие уложены друг на друга на столе, а третьи — собраны вместе для создания глобуса. Также нами была выбрана нужная точка обзора (ч1евро(пг).
Очевидно, мы хотели видеть угол комнаты с глобусом. Но как далеко от стены и где точно должна располагаться точка обзора? Нам нужно, чтобы в конечной сцене прнсутстновал хороший вид из окна, была видна часть пола, и все обьекты в спенс были не просто видны, но и представлены в интересном ракурсе. Эта глава абъясняет, как использовать Орепб1.
для решения следукппнх залач: позиционирование и ориентация модели в трехмерном пространстве и определение положення (также и в трехмерном пространстве) наблюдателя, Все зто помогает точно определить, какое изображение получится на экране. , Вам следует помнить, что суть компьютерной графики состоит н создании двухкерных образов трехмерных объектов (онн должны быть двухмерными, поскольку рисуются на плоском экране), но, принимая решения, определявшие, что именно рисуется на экране, валт следует представлять объект в трех измерениях.
Обшее заблуждение состоит в том, что при создании трехмерной графики многие с самого начала полагают, что результирующее изображение появится па плоском двумерном экране. 11ерестаньте думать о том, какие пикселы нужно рисовать, а вместо этого пытайтесь передать трехмерный мир. Представьте модель в - некоторой 30-вселенной, находящейся внутри вашего компьютера, и доверьте последнему работу по прорисовке нужных пикселов. Совокупность трех операций позволяет компьютеру преобразовать координаты трехмерных обьектов в положение пикселов на экране: ° Трансформации, реализуемые умножением матриц, в том числе моделирование, визуализация и проецирование.
К таким операциям относятся врашение, перемещение, масштабирование, отражение, ортогональная и перспективная проекции. Сцена строится с помошью комбинации нескольких операций. ° Так как сцена рисуется в прямоугольном окне, объекты (или части объектов), оказывающиеся вне этого окна, должны быть отсечены.