Увлекаясь компьютерной графикой, заметил, что комбинация правил и случайности может давать неожиданно красивые результаты.
С одной стороны, глядя на такие изображения очевидно их компьютерное происхождение, с другой — фактор случайности делает их неповторимыми и непредсказуемыми.
Еще подметил, что многократное повторение даже неказистых форм создает гармоничные рисунки, если видеть их целиком.
Как и большинство программистов, написал много рисующего кода, начинал еще в 1993 на Basic для Спектрумов, потом Pascal, С++. Мониторы становятся все лучше, разрешение все больше, процессоры все быстрее, и решил я «вспомнить молодость» :) Написал на C# (с использованием GDI+) очередного электронного художника.
Алгоритм прост:
Вот и всё, готово. При желании можно выполнить небольшую постобработку.
Код незамысловат:
и
и
Скомпилировано под .NET 4 (запускаю на Win7 64-bit). Максимальное разрешение изображения получается 460 мегапикселей (квадрат со стороной 22 тыс пикселов). Каждая картинка генерится несколько секунд.
Конечно, не все сочетания случайных параметров получаются удачными. Из десятка случайных картинок я на глазок отбираю лишь пару наиболее удачных. Таким образом, минут за 15 можно нагенерировать неколько десятков уникальных изображений.
Коллекцию нарисованных таким образом работ можно посмотреть тут и здесь (другой алгоритм). На досуге даже не поленился, сделал галерею этих рисунков на Silverlight с использованием DeepZoom
Примеры полученных описанным алгоритмом картинок:
P. S.: Добравшись с работы домой, обнаружил к статье много интересных комментариев. Спасибо за понимание! В качестве благодарности сообществу выкладываю в общий доступ скомпилированное приложение для экспериментов. Кому интересно — могу и код прислать. Сейчас там все параметры зашиты прямо в код. Требует dotNet Framework 4, размер генерируемого изображения — 4096 x 4096 пикселов. Делал для себя, так что интерфейс минималистичный. Кликайте на рисунок, чтобы сгенерить новый. Остальное — в меню.
P. P. S. По просьбам читателей выкладываю для изучения полностью исходники проекта (зеркало).
P. P. P. S. В комментариях и в личке есть просьбы рассказать об алгоритме «плюща». Алгоритм я описал в комментарии, а вот исходники и скомпилированный exe-шник (зеркало).
С одной стороны, глядя на такие изображения очевидно их компьютерное происхождение, с другой — фактор случайности делает их неповторимыми и непредсказуемыми.
Еще подметил, что многократное повторение даже неказистых форм создает гармоничные рисунки, если видеть их целиком.
Как и большинство программистов, написал много рисующего кода, начинал еще в 1993 на Basic для Спектрумов, потом Pascal, С++. Мониторы становятся все лучше, разрешение все больше, процессоры все быстрее, и решил я «вспомнить молодость» :) Написал на C# (с использованием GDI+) очередного электронного художника.
Алгоритм прост:
- Создаем случайную кривую линию случайного цвета;
- Многократно дублируем ее с постепенным поворотом вокруг «локального» центра, так чтобы получился «круг»;
- Этот «круг» несколько раз дублируем вокруг «общего» центра, тоже поворачивая, получается «слой»;
- Создаем таким образом несколько «слоев», накладывая друг на друга.
Вот и всё, готово. При желании можно выполнить небольшую постобработку.
Код незамысловат:
Parameters.Color = GetRandomColor();
var stars = new Star[Parameters.Random.Next(Parameters.MinStarCount, Parameters.MaxStarCount)];
for (var i = 0; i < stars.Length; i++)
{
stars[i] = new Star();
stars[i].GenerateRandom();
}
progressBar.Maximum = stars.Length + 1;
var bitmap = new Bitmap(Parameters.PictureSide, Parameters.PictureSide);
progressBar.Increment(1);
using (var gr = Graphics.FromImage(bitmap))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.Clear(Color.Empty);
gr.TranslateTransform((float)bitmap.Width / 2, (float)bitmap.Height / 2);
foreach (var star in stars)
{
star.Draw(gr);
progressBar.Increment(1);
}
}
pictureBox.Image = bitmap;
и
public void Draw(Graphics gr)
{
var rad = Parameters.PictureSide / 2;
float radius = Parameters.Random.Next(Splines.Spline.MaxRadius, rad - Splines.Spline.MaxRadius);
try
{
Splines.Start();
float phase = Parameters.Random.Next(360);
var oldMatrix = gr.Transform;
for (var i = 0; i < RayCount; i++)
{
var angle = 360f * (i / (float)RayCount);
gr.RotateTransform(phase + angle);
gr.TranslateTransform(radius, 0);
Splines.Draw(gr);
gr.Transform = oldMatrix;
}
}
finally
{
Splines.Stop();
}
}
и
public void Draw(Graphics gr)
{
var oldMatrix = gr.Transform;
for (var i = 0; i < _rotateCount; i++)
{
var angle = 360f * (i / (float)_rotateCount);
gr.RotateTransform(angle);
Spline.Draw(gr);
gr.Transform = oldMatrix;
}
}
Скомпилировано под .NET 4 (запускаю на Win7 64-bit). Максимальное разрешение изображения получается 460 мегапикселей (квадрат со стороной 22 тыс пикселов). Каждая картинка генерится несколько секунд.
Конечно, не все сочетания случайных параметров получаются удачными. Из десятка случайных картинок я на глазок отбираю лишь пару наиболее удачных. Таким образом, минут за 15 можно нагенерировать неколько десятков уникальных изображений.
Коллекцию нарисованных таким образом работ можно посмотреть тут и здесь (другой алгоритм). На досуге даже не поленился, сделал галерею этих рисунков на Silverlight с использованием DeepZoom
Примеры полученных описанным алгоритмом картинок:
P. S.: Добравшись с работы домой, обнаружил к статье много интересных комментариев. Спасибо за понимание! В качестве благодарности сообществу выкладываю в общий доступ скомпилированное приложение для экспериментов. Кому интересно — могу и код прислать. Сейчас там все параметры зашиты прямо в код. Требует dotNet Framework 4, размер генерируемого изображения — 4096 x 4096 пикселов. Делал для себя, так что интерфейс минималистичный. Кликайте на рисунок, чтобы сгенерить новый. Остальное — в меню.
P. P. S. По просьбам читателей выкладываю для изучения полностью исходники проекта (зеркало).
P. P. P. S. В комментариях и в личке есть просьбы рассказать об алгоритме «плюща». Алгоритм я описал в комментарии, а вот исходники и скомпилированный exe-шник (зеркало).