Перейти к основному содержимому

Примеры фигур на Processing/p5.js


Основы рисования на p5.js

p5.js — библиотека JavaScript для рисования и анимации прямо в браузере. Её часто ставят на курсах по творческому программированию, медиа-арту и веб-дизайну. Processing — старший брат на Java: те же идеи (setup, draw, линии, круги, цвета), другой синтаксис.

С чего начать

Теория по Canvas — Canvas 2D. Тот же стиль «черепашки», но на Python — примеры Turtle. Вектор в HTML без Canvas — SVG — рисунки кодом. 3D — Panda3D. Здесь — готовые скетчи p5.js с разбором строк: скопировали в редактор, нажали ▶, получили картинку.

Кому подойдёт эта страница

Школьникам — квадрат, домик, цветок для урока информатики или проекта. Студентам — фракталы, спирали, анимация для лабораторной. Начинающим на JavaScript — первый визуальный результат без React и сборщиков. Ищете «нарисовать квадрат p5.js», «processing цветок код», «снежинка processing» — примеры ниже с пояснением, зачем каждая строка.

Как запустить пример за 30 секунд

  1. Откройте editor.p5js.org — бесплатный онлайн-редактор, регистрация необязательна.
  2. Слева вкладка sketch.js — удалите шаблонный код.
  3. Вставьте код из примера целиком (включая функции turtleForward / turtleLeft, если они есть в блоке).
  4. Нажмите кнопку ▶ Play (или Ctrl+Enter).
  5. Справа появится холст с рисунком. Ошибка в консоли внизу — красная строка; чаще всего опечатка или забыли скопировать вспомогательные функции.

Локально: файл index.html + sketch.js (каркас в разделе ниже).

ГдеПлюсы
editor.p5js.orgНичего не ставить, сразу рисовать
HTML + CDNСвой сайт, портфолио, урок офлайн
Processing IDE (Java)Десктоп, похожий API, см. таблицу в конце

Базовые термины

ТерминПростыми словами
setup()Запускается один раз при старте: создать холст, фон, нарисовать статичную картинку
draw()Вызывается много раз подряд (каждый кадр) — анимация, игры, интерактив
createCanvas(w, h)Создаёт «лист» для рисования размером w×h пикселей
background(...)Заливает весь холст цветом (как ластик + заливка)
stroke / fillЦвет контура и заливки фигуры
line, rect, circleЛиния, прямоугольник, круг/эллипс
translate, rotateСдвинуть начало координат, повернуть систему осей
push / popСохранить и вернуть настройки (как «я рисую здесь, потом вернусь»)
noLoop()Остановить повтор draw() — для одной картинки без анимации

Какую фигуру выбрать

Вы ищете…Пример нижеИдея
Квадрат, многоугольникКвадрат, n-угольникЦикл + поворот на 360°/n
ТреугольникТреугольник3 стороны, поворот 120°
Дом, крышаДомикПрямоугольник + два наклонных ребра
ЦветокЦветокКруги по кругу или дуги
СнежинкаСнежинкаЛучи из центра
Дерево, фракталДерево, КохРекурсия — функция вызывает себя
Спираль, розаСпираль, РозаФормула в полярных координатах
ДвижениеАнимацияdraw() без noLoop()

Обязательный каркас

Любой статичный скетч строится по схеме: холст → фон → рисование → стоп.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);

// здесь ваш рисунок

noLoop();
}

function draw() {
// для анимации: уберите noLoop() и рисуйте здесь каждый кадр
}

Разбор:

  • function setup() — p5.js сам вызывает эту функцию при загрузке страницы; писать setup() вручную не нужно.
  • createCanvas(400, 400) — окно 400×400 px; width и height потом доступны как переменные.
  • background(255) — белый фон (одно число = оттенки серого 0…255). Цвет RGB: background(255, 0, 0) — красный.
  • angleMode(DEGREES) — углы в градусах (90° = прямой угол). По умолчанию в p5 — радианы; для школы удобнее градусы.
  • noLoop() — после первого кадра draw() больше не вызывается; картинка «замирает». Для GIF-подобной анимации noLoop() не ставят.

Локальный запуск — index.html:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.0/lib/p5.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

Разбор:

  • Строка <script src="...p5.min.js"> подключает библиотеку с CDN (интернет нужен один раз при загрузке).
  • sketch.js — ваш код с setup() и draw(); имя файла может быть любым, если путь в HTML совпадает.
Система координат

Точка (0, 0)левый верхний угол холста. X растёт вправо, Y — вниз (как в Canvas и в Turtle на экране). Центр экрана: translate(width / 2, height / 2) — так фигура оказывается посередине, а не в углу.

Типичные ошибки новичков
  • Белый экран — забыли нарисовать что-то в setup() или координаты за пределами холста.
  • turtleForward is not defined — не скопировали вспомогательные функции черепашки из раздела ниже.
  • Фигура «уехала» в угол — не сделали translate(width/2, height/2).
  • Анимация не идёт — стоит noLoop(); уберите для draw().
  • Углы «не те» — добавьте angleMode(DEGREES) или переводите радианы через radians(90).

Вспомогательные функции «черепашки»

На Python есть модуль turtle с командами forward и left. В p5.js их нет — добавляем один раз в начало файла (перед setup):

function turtleForward(len) {
line(0, 0, len, 0);
translate(len, 0);
}

function turtleLeft(deg) {
rotate(deg);
}

Разбор:

  • После translate и rotate «вперёд» — это ось X в текущем направлении; линия идёт от (0,0) до (len, 0) в локальных координатах.
  • translate(len, 0) переносит «черепашку» в конец отрезка — следующая линия продолжит контур.
  • rotate(deg) поворачивает всю систему координат на deg градусов (при angleMode(DEGREES)).

Перед каждой фигурой:

push(); // запомнить текущие translate/rotate/цвета
translate(width / 2, height / 2); // центр холста
// … рисуем …
pop(); // вернуть как было — не ломать следующие фигуры

Стартовые фигуры

Пять типов, которые чаще всего ищут вместе с Turtle и Processing: квадрат, треугольник, домик, цветок, снежинка. Дальше — сетки, фракталы и функции.


Квадрат на p5.js (как forward + left в Turtle)

Четыре стороны, каждый поворот 90°. Длина стороны 100 px — меняйте на своё.

function turtleForward(len) {
line(0, 0, len, 0);
translate(len, 0);
}
function turtleLeft(deg) {
rotate(deg);
}

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
stroke(0);
strokeWeight(2);
noFill();

push();
translate(width / 2, height / 2);
for (let i = 0; i < 4; i++) {
turtleForward(100);
turtleLeft(90);
}
pop();

noLoop();
}

Разбор:

  • stroke(0) — чёрный контур; noFill() — без заливки, только линии.
  • strokeWeight(2) — толщина линии 2 px.
  • for (let i = 0; i < 4; i++) — цикл 4 раза: 4 стороны квадрата.
  • turtleForward(100) — сторона 100 px; turtleLeft(90) — поворот на прямой угол налево (против часовой в математической системе, но p5 рисует Y вниз — визуально получается привычный квадрат).
  • push / pop — изоляция: после квадрата координаты не «сломаны» для других объектов.

Что изменить: 100150 — больший квадрат; цикл i < 6 и turtleLeft(60)шестиугольник (360÷6 = 60°).


Равносторонний треугольник

Три стороны, внешний угол 120° (180° − 60° угла треугольника).

function turtleForward(len) {
line(0, 0, len, 0);
translate(len, 0);
}
function turtleLeft(deg) {
rotate(deg);
}

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
stroke(0);
strokeWeight(2);
noFill();

push();
translate(width / 2, height / 2);
for (let i = 0; i < 3; i++) {
turtleForward(100);
turtleLeft(120);
}
pop();

noLoop();
}

Разбор:

  • i < 3 — три итерации, три ребра.
  • 120 — поворот между сторонами равностороннего треугольника; формула для правильного n-угольника «черепашкой»: поворот = 360 / n снаружи… для треугольника внутренний 60°, снаружи 120°.

Связь с математикой: сумма внешних углов любого выпуклого многоугольника = 360°.


Домик (стены + крыша)

Прямоугольник из четырёх сторон и две линии крыши под 45°.

function turtleForward(len) {
line(0, 0, len, 0);
translate(len, 0);
}
function turtleLeft(deg) {
rotate(deg);
}

function setup() {
createCanvas(400, 400);
background(240);
angleMode(DEGREES);
stroke(50);
strokeWeight(2);
fill(200, 180, 140);

push();
translate(width / 2 - 50, height / 2 + 50);

for (let i = 0; i < 4; i++) {
turtleLeft(90);
turtleForward(100);
}

turtleLeft(45);
turtleForward(70);
turtleLeft(90);
turtleForward(70);

pop();
noLoop();
}

Разбор:

  • fill(200, 180, 140) — бежевые стены; контур остаётся stroke(50) — тёмно-серый.
  • Сначала цикл рисует стены (4 поворота по 90°).
  • После цикла turtleLeft(45) + forward(70) — наклонная первая половина крыши; left(90) + forward(70) — вторая.
  • translate(width/2 - 50, height/2 + 50) — сдвиг, чтобы дом стоял по центру и «на земле», а не уехал вверх.

Что изменить: fill(255, 0, 0) — красные стены; 7090 — более острая или пологая крыша.


Простой красный цветок

Шесть маленьких кругов-лепестков вокруг центра + жёлтая серединка.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noFill();
stroke(220, 30, 60);
strokeWeight(3);

push();
translate(width / 2, height / 2);
for (let i = 0; i < 6; i++) {
circle(0, -30, 60);
rotate(60);
}
noStroke();
fill(255, 220, 0);
circle(0, 0, 20);
pop();

noLoop();
}

Разбор:

  • circle(x, y, d) — круг с диаметром d (не радиусом!). Центр лепестка: (0, -30) — на 30 px выше центра цветка.
  • rotate(60) после каждого лепестка — 360÷6 = 60° между лепестками.
  • Второй проход: noStroke() убирает контур, fill жёлтый — рисуем серединку circle(0, 0, 20).

Аналог в Turtle: цветок из circle — там t.circle(30) и t.right(60).


Цветок из кругов с заливкой (розовый)

Те же 6 лепестков, но залитые круги большего размера — лепестки перекрываются.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noStroke();
fill(255, 182, 193);

push();
translate(width / 2, height / 2);
for (let i = 0; i < 6; i++) {
circle(0, -50, 100);
rotate(60);
}
pop();

noLoop();
}

Разбор:

  • noStroke() — только заливка, без обводки.
  • circle(0, -50, 100) — лепесток дальше от центра (−50) и шире (диаметр 100).

Что изменить: i < 8 и rotate(45) — восемь лепестков; fill(255, 0, 255) — фиолетовый.


Простая снежинка

Восемь лучей из центра — поворот на 45° между лучами.

function setup() {
createCanvas(400, 400);
background(20, 30, 50);
angleMode(DEGREES);
stroke(100, 220, 255);
strokeWeight(2);

push();
translate(width / 2, height / 2);
for (let i = 0; i < 8; i++) {
line(0, 0, 50, 0);
rotate(45);
}
pop();

noLoop();
}

Разбор:

  • Тёмный фон background(20, 30, 50) — контраст с голубыми лучами.
  • line(0, 0, 50, 0) — отрезок длиной 50 от центра; без translate после линии все лучи стартуют из одной точки — это и нужно.
  • 8 лучей × 45° = 360°.

Усложнение: на конце каждого луча нарисуйте маленький line — классическая «веточка» снежинки (см. снежинку Коха).


Многослойный цветок

Три слоя лепестков разного цвета + жёлтый центр. Функция arcLeaf рисует один лепесток через кривую Безье.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noStroke();

push();
translate(width / 2, height / 2);

fill(173, 216, 230);
for (let i = 0; i < 12; i++) {
arcLeaf(80, 60);
rotate(30);
}

fill(144, 238, 144);
for (let i = 0; i < 8; i++) {
arcLeaf(60, 60);
rotate(45);
}

fill(255, 220, 0);
circle(0, 0, 30);

pop();
noLoop();
}

function arcLeaf(r, spread) {
beginShape();
vertex(0, 0);
bezierVertex(r, -spread, r, spread, 0, 0);
endShape(CLOSE);
}

Разбор:

  • Три цикла — три «яруса» лепестков; у каждого свой fill и шаг поворота.
  • beginShape()endShape(CLOSE) — произвольный многоугольник/заливка по точкам.
  • bezierVertex — сглаженная кривая; лепесток похож на каплю, а не на круг.

Фрактальное дерево с рекурсией

Функция drawTree рисует ветку и вызывает сама себя для двух ответвлений — получается дерево.

let depth = 6;

function setup() {
createCanvas(400, 400);
background(173, 216, 230);
angleMode(DEGREES);
strokeWeight(2);

push();
translate(width / 2, height - 20);
rotate(-90);
drawTree(100, depth);
pop();

noLoop();
}

function drawTree(len, level) {
if (level === 0) return;

const brown = map(level, 0, depth, 100, 180);
stroke(brown, 100, 50);
line(0, 0, len, 0);
translate(len, 0);

push();
rotate(30);
drawTree(len * 0.7, level - 1);
pop();

push();
rotate(-30);
drawTree(len * 0.7, level - 1);
pop();
}

Разбор:

  • depth = 6 — глубина рекурсии; level === 0базовый случай: дальше не рисуем (иначе бесконечность).
  • translate(width/2, height-20) + rotate(-90) — ствол растёт вверх от низа экрана (ось Y в p5 смотрит вниз, поэтому −90°).
  • map(level, 0, depth, 100, 180) — чем выше ветка, тем светлее коричневый (иллюзия освещения).
  • len * 0.7 — каждый уровень короче на 30%; угол ±30° — развилка.
  • push/pop вокруг каждой ветви — после левой ветки координаты восстанавливаются для правой.

Осторожно: depth больше 10 — тормоза; для отчёта хватит 5–7.


Сердце (кривые Безье)

Готовая «картинка на 14 февраля» — одна фигура из двух кривых.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noStroke();
fill(220, 30, 60);

push();
translate(width / 2, height / 2 + 20);
rotate(-50);
beginShape();
vertex(0, 0);
bezierVertex(0, -50, 100, -50, 100, 0);
bezierVertex(100, 50, 0, 80, 0, 0);
endShape(CLOSE);
pop();

noLoop();
}

Разбор:

  • bezierVertex(cx1, cy1, cx2, cy2, x, y) — кривая к точке (x,y) с двумя «ручками» управления.
  • Две такие кривые дают симметричное сердце; rotate(-50) наклоняет фигуру.

Квадрат из точек (двойной цикл)

8×8 сетка чёрных кружков — классика «циклы внутри цикла».

function setup() {
createCanvas(400, 400);
background(255);
noStroke();
fill(0);

const step = 25;
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const x = width / 2 - 100 + col * step;
const y = height / 2 - 100 + row * step;
circle(x, y, 12);
}
}

noLoop();
}

Разбор:

  • Внешний цикл row — строки, внутренний col — столбцы; всего 64 точки.
  • width/2 - 100 — смещение сетки к центру; col * step — шаг 25 px между точками.
  • circle(x, y, 12) — диаметр точки 12 px.

Шахматная сетка из точек

Тот же двойной цикл, цвет зависит от (row + col) % 2.

function setup() {
createCanvas(400, 400);
background(255);
noStroke();

const size = 30;
const startX = width / 2 - 120;
const startY = height / 2 - 120;

for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const x = startX + col * size;
const y = startY + row * size;
fill((row + col) % 2 === 0 ? 0 : 255);
circle(x + size / 2, y + size / 2, size);
}
}

noLoop();
}

Разбор:

  • (row + col) % 2 === 0 — чётная сумма индексов → чёрная клетка, нечётная → белая (как шахматная доска).
  • Тернарный оператор условие ? a : b — короткая запись if/else для цвета.

Сетка квадратов

Вместо circlerect в двойном цикле 3×3.

function setup() {
createCanvas(400, 400);
background(255);
stroke(0);
strokeWeight(1);
noFill();

const step = 30;
const startX = width / 2 - 50;
const startY = height / 2 - 50;

for (let row = 0; row < 3; row++) {
for (let col = 0; col < 3; col++) {
const x = startX + col * step;
const y = startY + row * step;
rect(x, y, 20, 20);
}
}

noLoop();
}

Разбор:

  • rect(x, y, w, h) — левый верхний угол (x,y), ширина и высота 20.
  • step = 30 — расстояние между началами квадратов; квадрат 20×20 — зазор 10 px.

Примеры фигур (функции и формулы)

Когда базовые циклы освоены, выносите рисование в функции — один раз написали drawStar, вызываете с разными параметрами.


1. Базовые многоугольники

1.1. Равносторонний треугольник через вершины

Вместо «черепашки» — три точки на окружности через cos / sin.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);

push();
translate(width / 2, height / 2);
drawEquilateralTriangle(100);
pop();

noLoop();
}

function drawEquilateralTriangle(side, doFill = false) {
stroke(0);
strokeWeight(2);
doFill ? fill(100, 150, 255) : noFill();

beginShape();
for (let i = 0; i < 3; i++) {
const a = -90 + i * 120;
vertex(cos(a) * side, sin(a) * side);
}
endShape(CLOSE);
}

Разбор:

  • -90 — первая вершина «сверху» (как на часах в 12).
  • cos(a) * side, sin(a) * side — координаты на окружности радиуса side.
  • doFill = false — необязательный параметр; drawEquilateralTriangle(100, true) зальёт треугольник голубым.

1.2. Прямоугольник и квадрат

function setup() {
createCanvas(400, 400);
background(255);

push();
translate(width / 2, height / 2);
drawRectangle(100, 200);
pop();

noLoop();
}

function drawRectangle(w, h, doFill = false) {
stroke(0);
strokeWeight(2);
doFill ? fill(180, 200, 255) : noFill();
rectMode(CENTER);
rect(0, 0, w, h);
}

Разбор:

  • rectMode(CENTER)rect(0, 0, w, h) рисует от центра, а не от угла; удобно после translate(width/2, height/2).
  • drawRectangle(100, 100) — квадрат; (100, 200) — вытянутый прямоугольник.

1.3. Правильный n-угольник

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);

push();
translate(width / 2, height / 2);
drawRegularPolygon(5, 100);
pop();

noLoop();
}

function drawRegularPolygon(n, radius, doFill = false) {
if (n < 3) return;
stroke(0);
strokeWeight(2);
doFill ? fill(255, 200, 100) : noFill();

beginShape();
for (let i = 0; i < n; i++) {
const a = -90 + (360 / n) * i;
vertex(cos(a) * radius, sin(a) * radius);
}
endShape(CLOSE);
}

Разбор:

  • drawRegularPolygon(5, 100)пятиугольник; 6 — шестиугольник, 8 — восьмиугольник.
  • (360 / n) * i — равномерное распределение вершин по кругу.

2. Звёздчатые фигуры

2.1. Звезда с n лучами

Чередуются внешний и внутренний радиус — классическая «звёздочка».

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);

push();
translate(width / 2, height / 2);
drawStar(5, 100, 40);
pop();

noLoop();
}

function drawStar(points, outerR, innerR, doFill = false) {
stroke(0);
strokeWeight(2);
doFill ? fill(255, 215, 0) : noFill();

beginShape();
for (let i = 0; i < points * 2; i++) {
const r = i % 2 === 0 ? outerR : innerR;
const a = -90 + (180 / points) * i;
vertex(cos(a) * r, sin(a) * r);
}
endShape(CLOSE);
}

Разбор:

  • points * 2 вершин — на каждый луч два радиуса (наружу и внутрь).
  • i % 2 === 0 — чётные шаги на внешнем круге, нечётные на внутреннем.
  • drawStar(5, 100, 40) — флаг с пятью лучами; innerR ближе к outerR — «толстая» звезда, дальше — острая.

Примеры вызова:

drawStar(5, 100, 40);
drawStar(6, 90, 45);
drawStar(8, 110, 50);

3. Цветочные и радиальные узоры

3.1. Цветок — лепестки по формуле

Лепестки на окружности радиуса radius через тригонометрию.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noStroke();
fill(255, 150, 180);

const petalCount = 10;
const radius = 100;
const petalR = 50;

push();
translate(width / 2, height / 2);
for (let i = 0; i < petalCount; i++) {
const a = radians(i * (360 / petalCount));
circle(cos(a) * radius, sin(a) * radius, petalR * 2);
}
pop();

noLoop();
}

Разбор:

  • i * (360 / petalCount) — угол i-го лепестка в градусах; radians(...) — p5 для cos/sin принимает радианы.
  • Центры лепестков лежат на окружности — цветок «ровный», в отличие от вращения одного круга.

3.2. Роза из дуг

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
noFill();
stroke(255, 105, 180);
strokeWeight(2);

push();
translate(width / 2, height / 2);
drawRose(5, 80);
pop();

noLoop();
}

function drawRose(petalCount, radius) {
for (let i = 0; i < petalCount; i++) {
push();
rotate(i * (360 / petalCount));
arc(0, -radius / 2, radius, radius, -60, 60);
pop();
}
}

Разбор:

  • arc(x, y, w, h, start, stop) — дуга эллипса от угла start до stop.
  • Каждый лепесток рисуется в своей повёрнутой системе координат (push/rotate/pop).

4. Фракталы

4.1. Дерево Пифагора

Похоже на рекурсивное дерево выше; угол 35° и другие пропорции — другой силуэт.

function setup() {
createCanvas(400, 400);
background(240, 248, 255);
angleMode(DEGREES);
strokeWeight(2);

push();
translate(width / 2, height - 30);
rotate(-90);
pythagorasTree(80, 7);
pop();

noLoop();
}

function pythagorasTree(len, depth) {
if (depth === 0) return;
stroke(map(depth, 0, 7, 80, 40), 120, 60);
line(0, 0, len, 0);
translate(len, 0);

push();
rotate(35);
pythagorasTree(len * 0.72, depth - 1);
pop();

push();
rotate(-35);
pythagorasTree(len * 0.72, depth - 1);
pop();
}

4.2. Снежинка Коха

Отрезок заменяется на «горку» ∧; повторяем — граница становится фракталом.

function setup() {
createCanvas(400, 400);
background(20, 30, 60);
angleMode(DEGREES);
stroke(180, 220, 255);
strokeWeight(1);

const side = 200;
push();
translate(width / 2, height / 2 + side / 3);
for (let i = 0; i < 3; i++) {
kochSide(side, 4);
rotate(120);
}
pop();

noLoop();
}

function kochSide(len, depth) {
if (depth === 0) {
line(0, 0, len, 0);
translate(len, 0);
return;
}
const third = len / 3;
kochSide(third, depth - 1);
push();
rotate(60);
kochSide(third, depth - 1);
pop();
push();
rotate(-60);
kochSide(third, depth - 1);
pop();
kochSide(third, depth - 1);
}

Разбор:

  • Три стороны равностороннего треугольника — цикл rotate(120).
  • depth = 4 — уже детальная снежинка; depth = 6 — тяжело для слабого ПК.
  • На depth === 0 рисуем простой отрезок — база рекурсии.

5. Параметрические кривые

5.1. Спираль Архимеда

Радиус растёт с углом: r = a + b·φ.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
stroke(0);
strokeWeight(1);
noFill();

push();
translate(width / 2, height / 2);
beginShape();
for (let deg = 0; deg < 360 * 5; deg += 2) {
const rad = radians(deg);
const r = 5 + 2 * rad;
vertex(cos(rad) * r, sin(rad) * r);
}
endShape();
pop();

noLoop();
}

Разбор:

  • 360 * 5 — пять оборотов; deg += 2 — шаг 2° (меньше шаг — гладче линия, больше точек).
  • 5 + 2 * rad — спираль расширяется от центра.

5.2. Полярная роза

r = a·cos(k·φ) — лепестки розы из школьной полярной системы координат.

function setup() {
createCanvas(400, 400);
background(255);
angleMode(DEGREES);
stroke(180, 50, 150);
strokeWeight(2);
noFill();

const k = 5;
const a = 100;

push();
translate(width / 2, height / 2);
beginShape();
const steps = k % 2 === 0 ? 720 : 360;
for (let deg = 0; deg <= steps; deg += 2) {
const rad = radians(deg);
const r = a * cos(k * rad);
vertex(cos(rad) * r, sin(rad) * r);
}
endShape();
pop();

noLoop();
}

Разбор:

  • k = 55 лепестков (k нечётное); k = 48 лепестков (2k при чётном k).
  • steps = 720 для чётного k — нужен двойной оборот, чтобы замкнуть кривую.

6. Анимации

6.1. Вращающийся цветок

Без noLoop()draw() крутится ~60 раз в секунду.

let angle = 0;

function setup() {
createCanvas(400, 400);
angleMode(DEGREES);
}

function draw() {
background(255);
noFill();
stroke(255, 105, 180);
strokeWeight(2);

push();
translate(width / 2, height / 2);
rotate(angle);
drawRose(6, 80);
pop();

angle += 2;
}

function drawRose(petalCount, radius) {
for (let i = 0; i < petalCount; i++) {
push();
rotate(i * (360 / petalCount));
arc(0, -radius / 2, radius, radius, -60, 60);
pop();
}
}

Разбор:

  • background(255) каждый кадр — стирает прошлый кадр (иначе шлейф из лепестков).
  • angle += 2 — поворот на 2° за кадр; += 5 — быстрее.
  • Переменная angle объявлена вне функций — сохраняется между вызовами draw().

6.2. Пульсирующая спираль

В радиус добавлен sin(t) — спираль «дышит».

let t = 0;

function setup() {
createCanvas(400, 400);
angleMode(DEGREES);
}

function draw() {
background(20, 20, 40);
stroke(100, 200, 255, 180);
strokeWeight(1);
noFill();

push();
translate(width / 2, height / 2);
beginShape();
for (let deg = 0; deg < 360 * 8; deg += 3) {
const rad = radians(deg);
const r = (5 + t * 0.5) + (2 + sin(t * 0.05)) * rad;
vertex(cos(rad) * r, sin(rad) * r);
}
endShape();
pop();

t += 1;
}

Разбор:

  • Четвёртый аргумент stroke(..., 180)прозрачность 0…255.
  • t += 1 каждый кадр — время растёт, форма меняется.

7. Геометрические узоры

7.1. Замощение шестиугольниками («улей»)

Соты — шестиугольники со сдвигом нечётных рядов.

function setup() {
createCanvas(500, 400);
background(255);
angleMode(DEGREES);
stroke(200, 160, 0);
strokeWeight(1);
noFill();

const r = 25;
const cols = 8;
const rows = 6;
const dx = r * 3;
const dy = r * sqrt(3);

for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const x = 60 + col * dx + (row % 2) * (dx / 2);
const y = 50 + row * dy;
drawHex(x, y, r);
}
}

noLoop();
}

function drawHex(cx, cy, radius) {
push();
translate(cx, cy);
beginShape();
for (let i = 0; i < 6; i++) {
const a = 30 + i * 60;
vertex(cos(a) * radius, sin(a) * radius);
}
endShape(CLOSE);
pop();
}

Разбор:

  • sqrt(3) — высота правильного треугольника; dy = r * sqrt(3) — вертикальный шаг между рядами сот.
  • (row % 2) * (dx / 2) — каждый второй ряд сдвинут на полшага — классическая гексагональная сетка.

8. Processing (Java) и p5.js — отличия

АспектProcessing (Java)p5.js
СредаProcessing IDE, файлы .pdeБраузер, editor.p5js.org
Объявление setupvoid setup() &#123; size(400,400); &#125;function setup() &#123; createCanvas(400,400); &#125;
Типы переменныхint i = 0;, float x;let i = 0;, const x = 1;
Циклfor (int i = 0; i < 4; i++)for (let i = 0; i < 4; i++)
Цветfill(255, 0, 0);то же
Комментарий////

Логика фигур одинаковая: те же line, rect, ellipse, translate, rotate. Перенос с Processing на p5.js — в основном замена size на createCanvas и синтаксиса Java на JavaScript.


9. Переиспользуемый шаблон для своих проектов

function setup() {
createCanvas(800, 600);
angleMode(DEGREES);
pixelDensity(1);
background(255);

drawScene();

noLoop();
}

function draw() {
// анимация: уберите noLoop() и перенесите drawScene() сюда
}

function drawScene() {
push();
translate(width / 2, height / 2);
// ваши фигуры
pop();
}

Разбор:

  • pixelDensity(1) — на Retina-экранах не удваивает плотность пикселей (проще отладка размеров).
  • Вся сцена в drawScene() — легко переключить статику (setup + noLoop) и анимацию (draw без noLoop).

10. Что попробовать самому

ЗаданиеПодсказка
Звезда на новогодней открыткеdrawStar(5, 120, 50, true) + тёмный background
Логотип из трёх круговтри circle() с разным fill, частичное перекрытие
«Часы» — вращающаяся стрелкав draw(): line(0,0,0,-80) и rotate(frameCount)
Шестиугольник черепашкойцикл 6 раз, left(60)
Сравнить с Pythonтот же квадрат в Turtle и здесь — одна геометрия, два языка

11. Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").