http://habrahabr.ru/post/251419/
Возможно, кто-то помнит замечательную олдскульную космическую игру
Star Control 2. В свое время меня поразила огромная звездная карта с неизведанными планетами, которые предстояло исследовать на фоне разворачивающейся глобальной катастрофы. С тех пор как авторами были опубликованы исходные коды, игра была портирована под новым именем
The Ur-Quan Masters на большинство современных платформ.
Покопавшись в исходниках, я обнаружил простой алгоритм, генерирующий текстуры планет, и написал программу на Python, позволяющую генерировать аналогичные текстуры.
Алгоритм
- Формируем карту высот с помощью алгоритма Fault Formation («формирование разломов»)
- Раскрашиваем карту высот, используя опорные RGB цвета и градиент между ними
Формирование карты высот
- Создаем матрицу высот той же размерности, что и генерируемая текстура планеты. Север сверху, юг снизу, а горизонталь матрицы представляет собой круговую развертку планеты вдоль параллели. Значение высот может меняться только в пределах от 0 до 255, поэтому удобно отображать их оттенками серого цвета
- Заполняем матрицу базовым значением высоты (base elevation), например, 128:
![](//habrastorage.org/files/459/e4b/49d/459e4b49da174e58835c62c694afd31f.png)
- Генерируем две случайные непересекающиеся линии с севера на юг. Эти линии «формируют разлом» — делят поверхность планеты на две части, одну из которых мы поднимаем на фиксированную константу (elevation delta), а другую опускаем на эту же константу. Для наглядности пусть константа равна 10:
![](//habrastorage.org/files/dd7/674/0a5/dd76740a5b314a4b8d1dd6749abad1c2.png)
- Повторяем предыдущий пункт заданное количество раз (iterations num).
На рисунках ниже: 10 итераций, 100 итераций, 1000 итераций:
![](//habrastorage.org/files/937/cbe/dbb/937cbedbbd6c45e386fd49a6735e79b6.png)
![](//habrastorage.org/files/68e/397/7f3/68e3977f37c042dab33da1ed65b1342f.png)
![](//habrastorage.org/files/799/a77/1a8/799a771a849d4d6fa54261112e459888.png)
Раскрашивание карты высот RGB цветами
- Делим весь диапазон высот (от 0 до 255) на N более-менее равных частей с N + 1 опорными точками на границах этих частей
- Задаем RGB цвет для каждой опорной точки диапазона
- Вычисляем RGB цвет для всех промежуточных точек диапазона, линейно интерполируя компоненты цвета между опорными точками. Иными словами, заполняем значения высот градиентом между опорными цветами
- Генерируем текстуру планеты, заменяя каждую ячейку матрицы высот на вычисленный в предыдущем пункте RGB цвет
Вот несколько возможных вариантов раскрашивания одной и той же карты высот:
![](//habrastorage.org/files/a5d/2aa/e04/a5d2aae041d64ac786dd313e0bbac61b.png)
![](//habrastorage.org/files/074/56f/29d/07456f29d2c5498ba09e634183df5f95.png)
![](//habrastorage.org/files/22b/1af/989/22b1af98997646ec853f38d0edc207ea.png)
![](//habrastorage.org/files/f78/688/c0d/f78688c0dd704533842b9e45c68a789f.png)
![](//habrastorage.org/files/223/4a3/66b/2234a366bfd340a9afcc953daf4c1871.png)
Программа
Для запуска программы необходимо установить
Python 2.7 и несколько библиотек к нему:
NumPy,
PIL и
PyOpenGL.
Программу можно скачать из репозитория git:
https://github.com/barabanus/starcontrol
Программа состоит из двух независимых скриптов:
planet.py (генерирует текстуру), и
space.py (рисует вращающуюся планету с наложенной текстурой).
Некоторые особенности управления:
- Для изменения опорного цвета кликните левой кнопкой мыши на квадратике с цветом. В MacOS во всплывающем диалоге есть возможность сэмплировать цвет с экрана
- Для создания нового опорного цвета кликните левой кнопкой мыши на градиенте
- Для удаления опорного цвета кликните правой кнопкой мыши на квадратике с цветом
- Для сохранения текстуры кликните по ней левой кнопкой мыши. При этом запускается скрипт, рисующий вращающуюся планету с этой текстурой
Программа создавалась на MacOS, тестировалась на WinXP. Если вы нашли и смогли исправить ошибку в коде или украсили рендер — пишите и предлагайте изменения.