Очевидно, вам придется писать генератор двумерных шумов Перлина. Задача весьма творческая и интересная. Результирующая программа будет выдавать изображения, похожие на галлюцинации коня во время приема 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
Усложнение
Усложненная версия задания подразумевает:
- Обертку для класса Grid, совмещающую в себе 3 сетки – по одной на каждый цвет
- Возможность для обертки задавать так называемый TurnColor – цвет, который покомпонентно перемножаться с тем, который был получен из каждой сетки. Только после этой операции сетку стоит нормировать на 0-255 и отрезать лишнее.
- Интерфейс IKnotValuePlacer, который будет подаваться на вход классу сетки и будет задавать способ разместить точки на сетке не в произвольном порядке, а как-нибудь закономерно
- Добиться того, чтобы в main осталось только задание гармоник, TurnColor-ов и KnotValuePlacer-ов для составления шумов. Всю остальную функциональность – в том числе и по генерации конечного изображения в Bitmap необходимо вынести в отдельный класс
- Долго экспериментировать с гармониками, чтобы понять их природу и попытаться сделать что-нибудь осмысленное
- Наколбасить WPF-фронтенд для генератора шумов, потому что вручную задавать гармоники через код и пересобирать приложение – муторно. Не работайте с WPF напрямую – ознакомьтесь с MVVM-фреймворком Caliburn.Micro.