Генератор шумов Перлина

Название Perlin
Баллы от 6 до 9
Командная?

Очевидно, вам придется писать генератор двумерных шумов Перлина. Задача весьма творческая и интересная. Результирующая программа будет выдавать изображения, похожие на галлюцинации коня во время приема LSD. За консольную версию программы вы получите 6 баллов, а за усложненную - 9.

Как это устроено

Данная нам графическая плоскость разделяется на 3-4 сетки, по принципу – каждая следующая сетка с вдвое меньшим шагом, чем предыдущая:

Сетка

Ну вот примерно как-то так

В узлах каждой сетки проставляются произвольные значения (абсолютно произвольные), между узлами для каждой сетки отдельно делается билинейная (для наилучших результатов рекомендуется бикубическая интерполяция). Чтобы определить цвет точки (x,y) – складываются 3 интерполированных значения от каждой сетки в этой точке с разными коэффициентами (калибруется в процессе):

Color(x,y) = a*Grid1Color(x,y) + b*Grid2Color(x,y) + c*Grid3Color(x,y)

Чтобы сделать цветную картинку, нужно просто проделать эту операцию для каждого из 3х цветов (R,G,B). Для простоты работать мы будем с квадратной сеткой

Пример использования:

Запуск lsd.exe 256 image.bmp – думает и выдает image.bmp, размером 256х256 пикселей, содержащий построенную указанным путем картинку

Подсказки

  • Для удобства лучше сделать класс Grid с конструктором от размеров требуемого изображения и «порядка» разбиения
  • У класса Grid можно сделать метод GetColor(x,y) выдающий float-значение интенсивности цвета в заданной точке. Потом эти значения удобно будет складывать. Для каждого цвета создать свой экземпляр Grid
  • Если значение интенсивности получилось меньше 0 – то урезаем до 0. Если больше 255, то урезаем до 255.
  • Random.Next(50,255) дает более-менее адекватные результаты Для рисования на виртуальных холстах хорошо подходит класс System.Drawing.Bitmap

Усложнение

Усложненная версия задания подразумевает:

  1. Обертку для класса Grid, совмещающую в себе 3 сетки – по одной на каждый цвет
  2. Возможность для обертки задавать так называемый TurnColor – цвет, который покомпонентно перемножаться с тем, который был получен из каждой сетки. Только после этой операции сетку стоит нормировать на 0-255 и отрезать лишнее.
  3. Интерфейс IKnotValuePlacer, который будет подаваться на вход классу сетки и будет задавать способ разместить точки на сетке не в произвольном порядке, а как-нибудь закономерно
  4. Добиться того, чтобы в main осталось только задание гармоник, TurnColor-ов и KnotValuePlacer-ов для составления шумов. Всю остальную функциональность – в том числе и по генерации конечного изображения в Bitmap необходимо вынести в отдельный класс
  5. Долго экспериментировать с гармониками, чтобы понять их природу и попытаться сделать что-нибудь осмысленное
  6. Наколбасить WPF-фронтенд для генератора шумов, потому что вручную задавать гармоники через код и пересобирать приложение – муторно. Не работайте с WPF напрямую – ознакомьтесь с MVVM-фреймворком Caliburn.Micro.