Генеративное искусство

Генеративное искусство основано на создании визуальных композиций с использованием алгоритмов, где итоговый результат определяется не вручную, а через правила, случайность и математические зависимости. Библиотека Paper.js предоставляет удобную среду для работы с векторной графикой и идеально подходит для подобных задач благодаря своей объектной модели, системе координат и встроенной поддержке геометрии.


Основные принципы генерации

Алгоритмичность Каждый визуальный элемент определяется набором правил: координаты, цвет, форма, поведение во времени.

Случайность (Randomness) Контролируемая случайность позволяет получать уникальные композиции при каждом запуске.

var x = Math.random() * view.size.width;
var y = Math.random() * view.size.height;

Повторяемость (Iteration) Циклы используются для создания множества элементов:

for (var i = 0; i < 100; i++) {
    new Path.Circle({
        center: Point.random() * view.size,
        radius: 10,
        fillColor: 'black'
    });
}

Правила трансформации Система может изменять элементы по определённым законам: смещение, вращение, масштаб.


Работа с координатами и пространством

Paper.js использует двумерную координатную систему, где начало находится в левом верхнем углу.

Генерация случайных точек:

var point = new Point(
    Math.random() * view.size.width,
    Math.random() * view.size.height
);

Нормализация координат:

var normalized = point.divide(view.size);

Это позволяет создавать адаптивные композиции, независимые от размера холста.


Создание органических форм

Шум и псевдослучайность

Использование шума (например, Perlin noise) даёт более естественные формы по сравнению с чистой случайностью.

Простейшая имитация:

function randomOffset(value, range) {
    return value + (Math.random() - 0.5) * range;
}

Генерация кривых

var path = new Path();
path.strokeColor = 'black';

for (var i = 0; i < 10; i++) {
    path.add(new Point(i * 50, randomOffset(200, 100)));
}

path.smooth();

Метод smooth() превращает ломаную линию в плавную кривую, что часто используется в генеративной графике.


Работа с цветом

Случайные цвета

var color = new Color(Math.random(), Math.random(), Math.random());

Градиенты

var gradient = new Gradient(['red', 'blue']);
var gradientColor = new GradientColor(gradient, view.bounds.topLeft, view.bounds.bottomRight);

Применение:

var rect = new Path.Rectangle(view.bounds);
rect.fillColor = gradientColor;

Цветовые системы

Использование HSL позволяет легче контролировать вариации:

var color = new Color({
    hue: Math.random() * 360,
    saturation: 1,
    lightness: 0.5
});

Повторяющиеся структуры и паттерны

Сетка (Grid)

var size = 40;

for (var x = 0; x < view.size.width; x += size) {
    for (var y = 0; y < view.size.height; y += size) {
        new Path.Circle({
            center: [x, y],
            radius: Math.random() * 10,
            fillColor: 'black'
        });
    }
}

Радиальные структуры

var center = view.center;

for (var i = 0; i < 360; i += 10) {
    var vector = new Point({
        length: 100,
        angle: i
    });

    new Path.Line({
        from: center,
        to: center + vector,
        strokeColor: 'black'
    });
}

Анимация генеративных систем

Paper.js поддерживает анимацию через onFrame.

function onFrame(event) {
    path.rotate(1);
}

Динамическое изменение параметров

function onFrame(event) {
    path.scale(1 + Math.sin(event.time) * 0.01);
}

Использование групп и иерархий

Группировка позволяет управлять сложными композициями:

var group = new Group();

for (var i = 0; i < 10; i++) {
    var circle = new Path.Circle({
        center: Point.random() * view.size,
        radius: 20,
        fillColor: 'black'
    });
    group.addChild(circle);
}

group.rotate(45);

Генеративные алгоритмы

Линейные алгоритмы

Простое последовательное построение:

var path = new Path();
path.strokeColor = 'black';

var point = view.center;

for (var i = 0; i < 50; i++) {
    point += new Point(Math.random() * 20 - 10, Math.random() * 20 - 10);
    path.add(point);
}

Фрактальные структуры

Рекурсивное деление:

function divideRect(rect, depth) {
    if (depth === 0) return;

    var horizontal = Math.random() > 0.5;

    if (horizontal) {
        var split = rect.height * Math.random();
        var top = new Rectangle(rect.topLeft, new Size(rect.width, split));
        var bottom = new Rectangle(
            rect.topLeft + [0, split],
            new Size(rect.width, rect.height - split)
        );
        divideRect(top, depth - 1);
        divideRect(bottom, depth - 1);
    } else {
        var split = rect.width * Math.random();
        var left = new Rectangle(rect.topLeft, new Size(split, rect.height));
        var right = new Rectangle(
            rect.topLeft + [split, 0],
            new Size(rect.width - split, rect.height)
        );
        divideRect(left, depth - 1);
        divideRect(right, depth - 1);
    }

    new Path.Rectangle({
        rectangle: rect,
        strokeColor: 'black'
    });
}

Взаимодействие с пользователем

Генеративные системы могут реагировать на действия:

function onMouseMove(event) {
    new Path.Circle({
        center: event.point,
        radius: Math.random() * 20,
        fillColor: 'black'
    });
}

Параметризация через ввод

var density = 50;

for (var i = 0; i < density; i++) {
    // генерация элементов
}

Работа с векторами

Paper.js предоставляет мощную работу с векторами:

var vector = new Point(100, 0);
vector = vector.rotate(45);

Использование в генерации:

var position = view.center;
var velocity = new Point(2, 3);

function onFrame() {
    position += velocity;
}

Оптимизация генеративных сцен

Минимизация объектов Слишком большое количество Path снижает производительность.

Использование Symbol Повторяющиеся элементы лучше создавать как символы:

var circle = new Path.Circle({
    radius: 10,
    fillColor: 'black'
});

var symbol = new SymbolDefinition(circle);

for (var i = 0; i < 100; i++) {
    symbol.place(Point.random() * view.size);
}

Удаление ненужных объектов

path.remove();

Комбинирование техник

Генеративное искусство часто строится на сочетании подходов:

  • случайные точки + сглаживание
  • сетки + шум
  • радиальные структуры + анимация
  • фракталы + цветовые градиенты

Пример комбинирования:

for (var i = 0; i < 200; i++) {
    var circle = new Path.Circle({
        center: Point.random() * view.size,
        radius: Math.random() * 30,
        fillColor: new Color({
            hue: Math.random() * 360,
            saturation: 0.7,
            lightness: 0.5
        })
    });

    circle.scale(Math.random());
}

Архитектура генеративного проекта

1. Инициализация сцены Создание холста и базовых параметров

2. Генерация данных Точки, структуры, параметры

3. Визуализация Создание Path, Group, Symbol

4. Анимация Обновление состояния

5. Взаимодействие Реакция на пользователя


Практические подходы

Контролируемый хаос Полностью случайные системы редко дают эстетичный результат. Ограничения делают композицию выразительной.

Повторяемость через seed Использование фиксированного генератора случайных чисел позволяет воспроизводить результат.

Модульность Разделение генерации, логики и визуализации упрощает развитие проекта.

Экспериментирование Небольшие изменения параметров могут радикально изменить результат.


Расширенные идеи

  • генерация ландшафтов
  • симуляция частиц
  • процедурные узоры
  • реактивные системы (звук → графика)
  • генерация типографики

Paper.js предоставляет фундамент для всех этих направлений благодаря удобной работе с геометрией и векторной графикой.