М. Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер - OpenGL. Руководство по программированию (Библиотека программиста) (2006) (1124363), страница 30
Текст из файла (страница 30)
поддерживают как минимум шесть дополнительных плоскостей отсечения, однако в некоторых реализациях их может быть больше. Чтобы узнать действительное количество, используйте функцию 916ет]псеае гч () со значением аргумента 6С ИАХ ССТР РСАМЕ5. ПРИМЕЧАНИЕ Отсечение выполняется в координатах глаза, а не в координатах отсечения. Зто различие заметно, если матрица проекций — вырожденная, (То есть матрица проекций по причине нулевого детерминанта переводит трехмерные координаты в двухмерные.) Пример отсечения Программа, приведенная в листинге 3.5, рисует каркас сферы с двумя плоскостями отсечения, которые отрезают три четверти сферы, как показано на рис.
3.23. Рис. 3.23. Усеченный каркас сферы Листинг 3.5. Каркас сферы с двумя плоскостями отсечения: сйр.с чо!б !и!г(чо!б) ( 9161еагса1ог(9.9, 9.0, 9.0, 9.0); 915набенобе!(61 РСАТ); чо!б б!зр1ау(чо!б) ( 6СбоцЫе ецп[4] = (9.9, 1.9, 0.9, 0.9); 6СбоцЫе ецп2[4] = ( 1.0, О.О. 0.9, 0.0); 9161еаг(6С СОСОМ ВОРРЕМ ВХТ); 91Со1огзт(1.9, 1,0, 1.0); 91Рцзннатг!х О; 91тгапз1агет(9.9, 9.0, -5.0); /' отсекаем нижнюю половину — у < 0 */ 9161!РР1апе(6С С[1Р РСАМЕВ. ецп); 91Епаые(6С СС1Р РСАМЕВ); /* отсекаем левую половину — х < 9 "/ 9161(РР\апе(6[ СЕ]Р РСАМЕ1, ецп2); 91ЕпаЫе(6С СС]Р РСАМЕ 1); Примеры объединения нескольких преобразований 135 л)лисасес(99.8, 1.0, 8.9, 0.0): 51игнгге5рьеге(1.9, 20, 16); 51Рорнагггх О; Л!Р1изп О; ) чоы гельаре(1пг н, ! пС П) ( 51Ч!енрогг(9, 8, (6(л1сег) н, (6(л1се1) П): 81Магг1хнобе(6С РЙОЗЕСТ10М); 81(оаб)бепг)гу О; Х1иРеглресг)че(60.0, (6(11оаг) иl(6(!1оаг) П, 1.8, 20.0); Л(МаСггхнобе (бг МООЕСН1ЕИ); !пг ла!п(зпг аглс, сьаг** аглч) ( 81иг1п!С(Магас, аглч); Л1иг1п1101зр1аунобе(ОСОТ 51МОСЕ ! 6ЕОТ ЛОВ); л1иг1п(СИ1пбон51се(588, 509); 81иг1п1гн1пбонРол111оп(199, 190); Е1игбгеагенчпбои(аглч(0)); сп1С(); 51иг01лр1аугипс(б1лр1ау): л1исмезпарегипс(гелпаре); 51иСМа)пгоор(); ге!игл 8: Упражнение ° Попробуйте изменить коэффициенты плоскостей отсечения в листинге 3.5.
° Попробуйте осуществить моделъно-виловое преобразование, например Ерсо гаге* (), для изучения функции к161! рР1ане () . Сделайте плоскости отсечения независимыми от объектов в сцене. Примеры объединения нескольких преобразований Этот раздел демонстрирует, как комбинировать несколько преобразований для получения требуемого результата. Он содержит два примера: солнечная система, ибьекты которой нужно вращать вокруг их осей и по их орбитам, и рука робота, ючлененная в нескольких местах, при движении которой преобразуются связанлие с суставами системы координат. Сплнечная система Программа, представленная в этом разделе, рисует простую Солнечную систему, слстоящую из Солнца и планеты, при помощи команд рисования сфер. Вращение солнца и планеты вокруг собственных осей реализовано командой к1йогаге* ().
136 Глава 3 ° Визуализация Для перемещения планеты по орбите применена команда 81тгап51ате*(). Требуемые размеры сфер зада!отея аргументами функции к!0!И! ге5 рве ге (). Для рисования Солнечной системы сначала нужно опрелелить модельно-виловые преобразования н преобразования проецирования. В данном примере используются команды 810Регзрестьуе() и 810Ьоохдт(). Рисование Солнца тривиально, поскольку Сольще неподвижно относительно начала фиксированной системы координат и перемещение не требуется. Для остального, то есть вращения Солнца вокруг оси, достаточно к\котате* () .
Рисование планеты, вращающейся вокруг Солнца, как показано на рис. 3.2/ь, требует нескольких модельных преобразований. Планета оборачивается вокруг своей оси за один день, а за год она совершает полный оборот вокруг Солнца. Рнс. 3.24. Солнце и планета Для определения порялка модельных преобразований представим, что происходит с локальььоьй системой координат.
Функция к1дотасе*() вращает локальную систему координат, которая изначально совпадала с фиксированной системой координат. Затем функция я1тгап51ате' () перемещает локальную систему координат в точку на орбите планеты. Расстояние переноса равно радиусу орбиты. Таким образом. функция 8180(ате* () определяет положение планеты па орбите (текущее время года). Затем вторая функция 81йоса1е* () поворачивает локальнуьо систему координат вокруг локальной оси, тем самым залавая время суток на планете. Когда все команды преобразований выполнены, рисуется планета. Итак, имитация Солнечной системы реализуется следуилцей последовательностью команд (полностью программа приведена в листинге 3.6): 81Ризьнасгьх(); 8!о!И! ге5рлеге(1.8, 20, 16); рисуем солнце '/ 81аотатет((6с(1оат) уеаг, 0.8, 1.0, О.О); 8!тгапз!атет(2.8. 0.0, 0.8); 8!Ялте(ет((81(!оет) ОаУ.
О.О, 1.8, 0.8); 8!осиьгезрпеге(8.2, 18. 8); /' рисуем планету */ 81Рорнасг!х(); примеры объединения нескольких преобразований 137 Листинг 3.б. Планетарная система: р(апе(.с !(а((с !пт уеаг = 8, бау = 0; чо!б !и!1(чо!б) ( 81С(еагсо(ог(0.0, 0.0, 0.0, 8,0); 515лабеиобе1(6С АУСАТ)'. ) чо!б б(ар1ду(чо(б) ( 51С(еаг(6С СОСОй ВОГРЕй 81Т); 51СЬ1огзг(1.8.
1.0. 1.8); 81Рцапид(гтх(), 51о(Н!ге5рлеге(1.0, 20, 16); /' рисуем солнце '/ В(йо1а1е(((6С(1оас) уеаг, 0.0, 1.0, О.О); 51Тгапа1а(ег(2.8, 0.0, 0.0); В(йо(асе(((6С()оа() бау, В.О, 1.8, В.О); 51о(И! ге5рлеге(0. 2, 10, В); /* рисуем планету */ 51Рарна 1 г ! х (); 51о(5нарво((ега(); ) чо(б ге!ларе(!пт н, (пс П) ( 5)ч!еирогт(8, О, (6са(ает) и, (6са!ае!) и)! 51насгтхиобе(6С Рйо)ЕСТ!ОН); 51(оаб(беп(!(у(); 51оРегарессчче(60.0, (6С(1ааС) и/(6С!\пас) П, 1.0, 20.0); е(ласт(хлебе(6( НООЕСУ)ЕН); 81Соаб(бент!Су(); 51о(ооХА((8.0, 0.8, 5.0, 0.0, 8.0, О.О, 0.0, 1.0.
О.О); чо!б Хеуьоагб(опа!Бпеб слаг Кеу, (пс х, !пт у) ( !и!тел (Кеу) ( сазе 'б': бау = (бау +1О) К 3 60; 81ц(Роатйеб(аР1аУ() Ьгеак: сапе '0': бау " (бау — 10) % 360: 81ц(Роа1йеб(аР1аУ(); Ьгеэх; саае 'у': уеаг = (уеаг +5) % 3 60, В)оспоасйеб!ар(ау(); Ьгеах; саае 'У': уеаг = (уеаг — 5) % 3 68; 81ц(Роасйебтар1ау(); Ьгеак; продолженое Р 138 Глава 3 к Визуализация Листинг З.б (продолжение) ветви!1: Ьгеах; 1пт па1п(1пт агкс.
сваг" агви) ( а)ит(п1!(аагас. агау); а)ит)п!(0(зр!ауиобе(СЬит ЬОВВЬ5 ! Сгит аСВ); В)ит)п1(И!пбои5!те(500, 500); В!ит)п1(Н!пбоиео51(1оп(100, 100); в!итсгеа(еу)!лбов(агат[0]); !п11(); а)и(0!зр)аурипс(б!ар!ау); а)итаезпарегипс(гезьаре)') а)иткеуЬоагбгипс(хеуЬоагб); а)и!на(п!.оор(); ге(игл 0; Упражнение ° Попробуйте добавить луну к планете или несколько луп и планет. Подсказка: используйте функции а) Ризбиатг(х() и а)Рарнатг(х() для хранения и восстановления положения и ориентации системы координат в требуемый момент времени. Если вы решили обзавестись несколькими спутниками, следует сохранять систему координат до позиционирования каждой луны и восстанавливать ее после рисования каждой луны.
° Попробуйте наклонить ось планеты. Сочлененная рука робота Этот раздел содержит программу, которая создает сочлененную руку робота из двух пли более сегментов. Рука должна быть подвижна в плече, локте нли других суставах. На рис. 3.25 приведена рука с одним подвижным суставом. Рис. 3.25. Рука робота Для рисования сегментов руки подходит масштабированный (вытянутыт1) куб, но сначала вам надо применить модельные преобразования для ориентирования каждого сегмента. Так как центр локальной системы координат изначально нахо- Примеры объединения нескольких преобразований 139 амгся в пентре куба, нужно переместить локальную систему координат к одной ю границ куба.
С другой стороны, хотя физически сустав двигается относительно шарнира, ло- шческн куб вращается вокруг своего центра. Поэтому после вызова функции 51Тгап51 а те* () для указания точки вращения и функции к! ВО Саге* () для вра- щеввя куба мы возвращаемся к центру куба. Затем, перед рисованием, куб мас- птабируется (сплющивается или растягивается). Функции к1ризьмасг!х() и 51рорнасг)х() ограничивают применение вносимого функцией к15са1е'() эф- фекта.
Код рисования первого сегмента руки будет выглядеть примерно так (пол- ная программа приведена в листинге 3.7); С!Тгап51аСеч(-!.8, О. О, 9. 0); с!Мосасег((ссг)оас) зьоо!Оег, 9.8, 9,9, !.9); 51тгап51агеч(!.8, 0.0, 0.8): 51РшП Ма! г ч х (); 5!5са1ег(2.0, 0.4, !.0); 51ЬСМ(геСЬЬе(!. 0); 5!Роряагг! х(); Поскольку система координат раз была повернута, ось х уже ориентирована месь длины руки. Таким образом, для рисования следующего сустава необходим перекос вдоль оси х локальной системы координат в следующую точку враще- аия. В этой точке вращения опять можно использовать приведенный выше код. Ди)ньш процесс можно прополжитгп переходя от сустава к суставу (плечо, ло- ють, запястье, пальцы): с!Тгппч)а(еч(1.8, 9.0, О.О), С!ао(4(е(((ОСЧ!оаС) е!Ьон, 0.9, 0,0, !.8); с!тгапчсасе((!.8. о.о, О.о), $1Рпчпнд(г1 х (); 5!544!еч(2.9, 0.4, 51ЬСМчгеСЬЬе(!.0); С!РЬРМа(гчх(); Ластинг 3.7.
Рука робота: гоЬос.с ч(зС!с чос чпоисоег = О, е1ьон = 0; чо!4 !п)С(хоче) ( с!С1еагсо1ог(8.8, 8.8, 8.0, 8.0); 415ьаоеМоее!(ОС ЕСАТ). ) чо!О 4!чр1ау(чо)д) ( 41С!еаг(ОС СО!Оп ВОРРЕМ ВТТ)," 41Розьна(г)х(); 61тгап51агеч(-!.8, 8.8, О.О); Х!Ко(агеч((ОСГ!Ьат) зпоо!пег, О.О, О.О, !.О); Х1тгапз)асес(1.8, О.О, 0.0); с1РочпнаСгчх(); 415са1ес(2.9, 8.4, 1.0); продолхгенив .О Обратные, или имитационные, преобразования 141 5!и!1п11(аагзс, агвч); 5!и!1п1101зр!ауМибе(бьет воив(Е ~ Всит ВВВ)! В!и11п1(й1пбой5(ке(500, 50В): 5!ис!п11й!пбойРоз!!!оп(100, 100): В!и!Сгеасей1пбой(агач(В)); (пз(О; В!и(015Р!аугипс(б)зр!ау): 5!исаезлареГипс(гезьаре): В!и(кеуЬоагбгипс(хеуЬоагб); З!и!Ма1псооо О; ге!игп О, Упражнение ° Измените листинг 3.7, добавив дополнительные сегменты к руке.