Графики и диаграммы давно стали привычными атрибутами научной литературы. Однако ими научная иллюстрация далеко не ограничивается. Нередко объект исследований настолько сложен (течение жидкости, движение системы твердых тел), что важно увидеть весь процесс происходящих в нем изменений целиком, иначе просто неясно какой график следует строить. Здесь на помощь ученым приходят средства трехмерной визуализации. Об одном из таких средств и пойдет наш рассказ.
Обычная кухня... Нет, это не фотография, а изображение, созданное в программе POV-Ray методом трассировки лучей. Представьте, что экран вашего компьютера — это окно, за которым что-то происходит. Это «что-то» называется сценой. Цвет каждого пикселя на экране — это цвет луча, который выходит из глаза, проходит через этот пиксель и сталкивается со сценой. Луч может просто вернуться назад, а может отразиться от зеркальной поверхности или преломиться, проходя, например, из воздуха в стекло. Чтобы узнать цвет, в который окрасится пиксель, нужно запустить через него луч и проследить путь этого луча по сцене. Отсюда произошло название алгоритма: ray-tracing — трассировка лучей.
Точнее, это обратная трассировка лучей. Ведь, как мы знаем, луч не выходит из глаза, а наоборот, попадает в него, проделав свой путь от источника света. Однако такая (прямая) трассировка требует огромных вычислительных ресурсов, ведь большая часть лучей пропадает даром, не попав в наше поле зрения. Подробнее физические основы метода обратной трассировки лучей изложены в книге Е. В. Шикина и А. В. Борескова «Компьютерная графика. Динамика, реалистические изображения» (М.: Диалог-МИФИ, 1995).
POV-Ray или, полностью — The Persistence of Vision Ray-Tracer — использует обратную трассировку лучей для создания трехмерных фотореалистических изображений. Сцена в POV-Ray описывается на SDL (Scene Description Language) — интерпретируемом языке программирования с С-подобным синтаксисом. При помощью SDL пользователь задает положение камеры, источников света, размещение объектов и их свойства, атмосферные эффекты и т. п.
Применение POV-Ray для научной иллюстрации — лишь малая часть среди возможных направлений использования этой программы. И даже с этой малой частью мы в статье успеем лишь познакомимся. Что ж, приступим…
Векторы и система координат. POV-Ray работает с вещественными числами и векторами. Вектором называется точка в пространстве, задаваемая как <x,y,z>. Координаты вектора могут быть числами или переменными, например: <1,.2,cos(alpha)>.
Система координат, принятая в POV-Ray по умолчанию, выглядит так:
Ось Z направлена внутрь монитора.
Чтобы получить изображение, нам понадобится объект для съемки, освещение, и камера. Вот с нее и начнем.
Камера. «Фотографию» сцены невозможно создать без камеры (camera). Точка, в которой расположена камера, задается параметром location, а параметр look_at определяет точку, куда она направлена. В качестве примера, поместим камеру в точку <0,0,-10> и направим ее в начало отсчета. Записывается это так:
camera
{
location <0,0,-10>
look_at <0,0,0>
}
Источник света. Разместим позади и справа от камеры источник света light_source:
light_source
{
<10,20,-20>
color <1,1,1>
}
Вектор <10,20,-20> определяет положение источника света, а вектор color — его цвет <R,G,B>. Яркость каждой из компонент цвета изменяется от 0 (полное отсутствие соответствующего цвета) до 1 (максимальная яркость).
По умолчанию, источник света невидим — это просто светящаяся точка, но его можно сделать видимым, а также привязать к любому объекту, как встроенному, так и созданному пользователем.
Простые объекты. POV-Ray располагает обширной библиотекой готовых объектов. Вот, например, как задается сфера:
sphere
{
<0,0,0>,2
}
Первый вектор определяет положение центра сферы, а следующее за ним число — ее радиус. Наша сфера расположена в начале координат и ее радиус равен 2.
Вставка готовых объектов POV-Ray при помощи меню Insert (POV-Ray для Windows).
По умолчанию, сфера окрашивается в черный цвет. Пигмент (краситель), задающий цвет объекта, определяется в блоке pigment:
sphere
{
<0,0,0>,2
pigment
{ color <1,1,1> }
}
Цвет пигмента задается точно также как цвет источника света. В нашем случае сфера будет окрашена в белый цвет.
Собирая все фрагменты вместе, получим:
camera
{
location <0,0,-10>
look_at <0,0,0>
angle 35
}
light_source
{
<10,20,-20>
color 1
}
sphere
{
<0,0,0>,2
pigment
{ color <1,1,1> }
}
Пора «попросить» POV-Ray оттрассировать это. Сохраним сцену в файле test.pov и запустим POV-Ray командой:
povray +itest +w320 +h240
Опция +i задает имя файла, из которого вводятся данные (input): test.pov (расширение указывать не обязательно, POV-Ray предполагает, что это будет .pov). Опции +w и +h с последующими цифрами задают ширину (width) и высоту (height) изображения в пикселах.
В POV-Ray для Windows трассировку можно выполнить с помощью меню:
Запуск трассировки сцены с помощью кнопки Run.
Вот что у нас получилось:
Для начала неплохо. Напоминает планету в космосе. Можно усилить это сходство, нанеся на поверхность сферы рельеф и текстуру. Как это сделать, описано здесь, а мы пойдем дальше.
Конструктивная геометрия. Новые тела можно получать из уже имеющихся при помощи операций объединения, слияния, разности, пересечения и т. п. Такой способ создания новых объектов называется конструктивной блочной геометрией (Constructive solid geometry, CSG).
Создадим изображение молекулы воды, состоящее из большой сферы — атома кислорода и двух малых сфер — атомов водорода:
sphere
{
<0,0,0>,2
pigment
{ color Red }
}
sphere
{
<1.5,0,0>,1.5
pigment
{ color White }
}
sphere
{
<1.5,0,0>,1.5
pigment
{ color White }
rotate <0,0,104.45> // угол между атомами водорода
}
Команда rotate вращает объект относительно начала отсчета. В данном случае мы повернули вторую из малых сфер на 104.45 градуса (т. е. на угол между атомами водорода в молекуле воды). Как видно, в POV-Ray, в отличие от многих языков программирования, углы задаются в градусах, а не в радианах.
Объединим теперь сферы в единый объект командой union. Полученному объекту можно присвоить имя и затем использовать его под этим именем в дальнейших расчетах. Назовем наш объект — H2O.
Объявляется объект командой declare, а непосредственно создается — командой object{имя_объекта}. Покажем, как построить объединение трех сфер:
#include "colors.inc"
...
#declare H2O =
union
{
sphere { <0,0,0>,2 pigment { color Red } }
sphere { <1.5,0,0>,1.5 pigment { color White } }
sphere { <1.5,0,0>,1.5
pigment { color White }
rotate <0,0,104.45>
}
}
object
{
H2O
rotate <0,0,36>
}
и получим:
Заметим, что после своего создания объект H2O поворачивается как единое целое на 36 градусов:
Названия цветов вроде Red и White — это имена векторов, объявленные в подключаемом файле colors.inc.
Применяя этот подход можно легко создать несколько объектов:
Немудрено, что POV-Ray активно используется для визуализации молекулярных структур (пример).
Анимация. POV-Ray позволяет создавать анимацию в виде последовательности кадров. Чтобы на этих кадрах что-то изменялось, нужна переменная, задающая время — она называется clock. Кроме того, нужно задать некоторые настройки, например, количество кадров. О настройках поговорим чуть позже, а пока рассмотрим пример:
camera
{
location <0, 3, -6>
look_at <0, 0, 0>
}
light_source { <20, 20, -40> color White }
plane
{
y, 0
pigment { checker color White color Black }
}
box
{
<-1, 0, -1> , <1, 2, 1>
pigment { color Green }
translate <clock, 0, 0>
}
Здесь вводятся два новых объекта — бокс box и плоскость plane. y — это вектор нормали к поверхности и равен он <0,1,0>.
Ключевой момент здесь — строка translate <clock, 0, 0>. Переменная clock, по умолчанию, равна 0 в начале анимации и 1 — в конце. Благодаря этому бокс должен переместиться на одну клетку вправо.
Теперь зададим число кадров. Номера первого и последнего кадров задаются параметрами Initial_Frame и Final_Frame. Initial_Frame по умолчанию равен 1, и менять его мы не собираемся, а Final_Frame зададим равным 20. Это делается в командной строке с помощью опции +KFF так: +KFF20.
Чтобы не писать каждый раз настройки в командной строке, поместим их в отдельный текстовый файл — my.ini. Настройки можно записывать точно так же, как в командной строке, или в более читабельном виде. В нашем примере INI-файл имеет вид:
Width=320
Height=240
Final_Frame=20
Теперь командная строка будет выглядеть так:
povray +iимя_файла my.ini
В результате получится последовательность из 20 кадров — графических файлов, которые затем можно будет преобразовать в видео. Для этого есть масса инструментов, например Virtualdub — широко распространенный, свободный и кроссплатформенный.
Вот что у нас получилось в итоге:
Цикл while. Допустим, нам нужно выполнять анимацию вплоть до заданного момента времени. Тогда нам пригодится цикл с условием:
#while (логическое_условие)
...
#end
Он будет выполняться до тех пор, пока остается истинным логическое условие, стоящее в скобках.
Давайте нарисуем бокс, поместим на его вершину шар, столкнем его и нарисуем что из этого получится:
#include "colors.inc"
light_source { <0,5,-50> color White }
light_source { <0,50,0> color White }
light_source { <10,2.5,0> color White }
camera { location <5,3,-10> look_at <1,3,0> }
#declare time = 0.0;
#declare px = 0.0;
#declare py = 5.0;
#declare vx = 5;
#declare vy = 0.0;
#declare g = 9.8;
box { <-5,py,2>, <0,-2,-2> pigment {Blue} }
plane { y, 0 pigment {Gray} }
#while (time <= clock)
#declare dt = clock_delta;
#declare px = px+vx*dt;
#declare py = py+vy*dt-0.5*dt*dt;
#declare vy = vy-g*dt;
sphere { <px,py,0>, 0.2 pigment {Green} }
#declare time = time + clock_delta;
#end
Координаты шара задаются переменными px, py, а его скорость — vx, vy. g — ускорение свободного падения. Если это вам ни о чем не говорит, то просто примите формулы на веру и сосредоточьтесь на рисовании.
Здесь в цикле изменяется «пользовательское» время time, увеличиваясь на каждом шаге на clock_delta. Я назвал это время так, потому что его состоянием пользователь может управлять по своему желанию, тогда как для clock можно задавать только диапазон изменения. На каждом шаге цикла рисуется все больше и больше шаров, до тех пор пока время рисования не закончится (т. е. достигнет значения Final_Clock).
Чтобы не рисовать «след» из шаров, достаточно вынести команду sphere за пределы цикла и поместить ее после #end.
Обратите внимание на то, что сцена освещена сразу тремя источниками света. Первый источник дает нам обычное освещение. Зачем тогда нужны два других? А вот зачем. Второй источник освещает сцену сверху и позволяет получить «дорожку» из теней шаров в горизонтальной плоскости. Третий — светит сбоку и дает тени шаров на вертикальной стенке бокса. Теперь мы можем увидеть, что вдоль координаты X шар движется равномерно, а вдоль Y — ускоряется. Пригодится в качестве наглядного примера на уроке физики, не так ли?
Заметим, что POV-Ray — не лучшее средство для моделирования движения, он все-таки только «рисователь». Обычно, движение моделируется с помощью какого-то из языков программирования (например, С), результаты сохраняются в виде команд POV-Ray, а уж тот рисует как двигалось тело. Но, как видим, если нужно, то простое моделирование можно выполнить и в самом POV-Ray.
Кроме цикла с условием #while, в POV-Ray есть и цикл со счетчиком — #for, есть условный оператор #if и блок выбора #switch, есть... Ну, вы поняли: много чего есть в POV-Ray, а статья не резиновая. Но перед тем как попрощаться…
Немного ссылок
Исходная точка для поиска дальнейшей информации по POV-Ray — официальные руководство и коллекция ссылок.
Домашняя страница Андреа и Фридриха Ломюллеров содержит множество руководств по POV-Ray, в частности, по анимации, галерею работ и ссылки на ресурсы, посвященные трассировке лучей.
Большая коллекция готовых объектов находится на сайте POVWorld.org.
На странице Пола Бурка находятся примеры использования POV-Ray для иллюстрации научных работ, например, для визуализации скалярных полей.
Рисунки причудливых математических объектов, в частности двух- и трехмерных фракталов, а также результаты моделирования различных физических процессов показаны на сайте Пола Ниландера.
В работе Пола Лютуса «Adventures in Ray Tracing», помимо введения в POV-Ray, описано создание с его помощью стереоизображений.
Применения POV-Ray в астрономии.
Вот теперь все. Удачи!
Дмитрий Храмов
![Версия для печати Версия для печати](https://www.kv.by/sites/all/modules/print/icons/print_icon.png)
Комментарии
Страницы
Здравствуйте! Рад, что статья все еще обсуждается. Хотел вставить и свои пять копеек, но извините, получилось копеек на двадцать.
Для начала уточню некоторые термины. Научная визуализация — это визуальное представление результатов научных расчетов. Сложность такого представления слабо связана со сложностью самих расчетов. Суперкомпьютеры могут считать неделями, но результат их работы уместится на простеньком графике. А может быть и совсем наоборот. В статье, конечно же, нет никакой новой «науки» из области компьютерной графики, не для того она.
Когда я писал эту статью, мне очень хотелось поделиться симпатичным инструментом, который позволил мне без особых хлопот рисовать интересующие меня объекты. Я «расчетчик», а не дизайнер или художник. До сих пор я пользовался OpenGL (и продолжаю им пользоваться), но это для меня все же слишком низкоуровневый инструмент. То, что в POV-Ray сцена создается как скрипт -- большой плюс для меня: теперь моя программа генерирует такой скрипт, POV-Ray его трассирует, а я получаю красивую картинку.
Я пытался написать элементарное введение в POV-Ray. Такое, чтобы можно было скачать программу и немедленно начать рисовать, но вместе с тем и получить представление о том, куда можно пойти дальше. Однако даже этой малости уже достаточно, чтобы визуализировать, например, движение жидкости как потока частиц (при условии, конечно, что координаты и скорости частиц известны). Потому и примеры просты, зато вы тут же можете их сами повторить и развить. Более хитрые штуки -- в ссылках, Гугле, ну и в вашей фантазии, конечно.
POV-Ray – не «симпотненькая скриптовая рисовалочка». Взгляните хотя бы на первый рисунок в статье. Мне нет нужды остаивать POV-Ray, просто считая так -- вы ошибетесь. Его скриптовость для кого-то минус (мне сложно представить художника, обходящегося только скриптами), а для кого-то, как для меня, существенный плюс -- у каждого инструмента свое место и своя сфера применения.
Уважаемый leo, ваш несколько пренебрежительный тон, когда речь идет о школьных уроках вызывает сожаление. У тех, кто создает анимашки и презенташки результат получается в рифму, а детям надо «как для взрослых, только лучше».
NetLogo я знаю и люблю, спасибо за упоминание. Лет пять назад даже читал с его помощью курс лекций по агентному моделированию. Очень интересная штука (NetLogo), если, конечно, не использовать его вместо С++.
Очень жаль, что на сайте нет плагина для отображения кода.
Абсолютно согласен. Сам работал учителем. Считаю это сейчас едва ли не самым важным делом.
Очень интересно! Был бы рад узнать где, а также пообщаться на эту тему.
Страничка курса: Агентное моделирование в геоинформационных системах. Читал в Горном университете (г. Днепропетровск, Украина).
Здесь немножко больше: есть заготовки к нескольким дипломам.
Записки эти весьма сырые. Тогда информации на русском почти не было, приходилось работать быстро, чтобы дать студентам хоть какую-то информацию. Надеюсь, они все же пригодятся.
Спасибо Дмитрий!
Мне очень интересно было посмотреть ваш сайт! У нас, пожалуй, довольно много общего:) Даже темы... клеточные автоматы и агентное моделирование... я тоже это включаю в свои курсы:)
Страницы