Как стать автором
Обновить

Закономерные случайности

Время на прочтение3 мин
Количество просмотров4.3K
Увлекаясь компьютерной графикой, заметил, что комбинация правил и случайности может давать неожиданно красивые результаты.

С одной стороны, глядя на такие изображения очевидно их компьютерное происхождение, с другой — фактор случайности делает их неповторимыми и непредсказуемыми.

Еще подметил, что многократное повторение даже неказистых форм создает гармоничные рисунки, если видеть их целиком.







Как и большинство программистов, написал много рисующего кода, начинал еще в 1993 на Basic для Спектрумов, потом Pascal, С++. Мониторы становятся все лучше, разрешение все больше, процессоры все быстрее, и решил я «вспомнить молодость» :) Написал на C# (с использованием GDI+) очередного электронного художника.

Алгоритм прост:
  1. Создаем случайную кривую линию случайного цвета;
  2. Многократно дублируем ее с постепенным поворотом вокруг «локального» центра, так чтобы получился «круг»;
  3. Этот «круг» несколько раз дублируем вокруг «общего» центра, тоже поворачивая, получается «слой»;
  4. Создаем таким образом несколько «слоев», накладывая друг на друга.


Вот и всё, готово. При желании можно выполнить небольшую постобработку.

Код незамысловат:

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-шник (зеркало).
Теги:
Хабы:
+138
Комментарии84

Публикации

Изменить настройки темы

Истории

Ближайшие события