Что такое фрактал и как его нарисовать на JavaScript?

Фракталы — это фигуры, которые обладают удивительным свойством: часть фрактала повторяет форму целого. Они находят применение в математике, природе, компьютерной графике и даже генеративном искусстве.
Что такое фрактал?
Фрактал — это геометрическая структура, обладающая самоподобием и строящаяся по рекурсивному алгоритму. Характерные признаки фракталов:
- Самоподобие — фрагменты фигуры похожи на целое.
- Рекурсивность — фигура строится путём повторения одного и того же правила.
- Бесконечная детализация — каждый уровень добавляет новые мелкие элементы.
Примеры фракталов в природе:
- снежинки
- папоротники
- молнии
- береговые линии
Пример 1: Фрактальное дерево
Фрактальное дерево — это структура, где из одного "ствола" растут две ветви, а из каждой ветви — ещё две, и так далее.
Полный код с комментариями:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Фрактальное дерево</title>
</head>
<body>
<canvas id="canvas" width="800" height="600" style="border:1px solid #ccc;"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
/**
* Рисует дерево рекурсивно
* @param {number} x - начальная x-координата (основание ветви)
* @param {number} y - начальная y-координата
* @param {number} length - длина ветви
* @param {number} angle - угол в радианах (π/2 = 90°, вертикально вверх)
* @param {number} depth - глубина рекурсии
*/
function drawTree(x, y, length, angle, depth) {
if (depth === 0) return; // базовый случай: остановка рекурсии
// Вычисляем конец текущей ветви с помощью тригонометрии
const x2 = x + length * Math.cos(angle);
const y2 = y - length * Math.sin(angle); // минус, потому что ось Y в canvas направлена вниз
// Рисуем текущую ветвь
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x2, y2);
ctx.stroke();
// Рекурсивно рисуем 2 подветви с уменьшенной длиной и разными углами
drawTree(x2, y2, length * 0.7, angle - Math.PI / 6, depth - 1); // левая ветвь (угол -30°)
drawTree(x2, y2, length * 0.7, angle + Math.PI / 6, depth - 1); // правая ветвь (угол +30°)
}
// Настройка линии
ctx.strokeStyle = 'green';
ctx.lineWidth = 2;
// Начало рисования дерева: из центра нижней части холста вверх
drawTree(400, 550, 100, Math.PI / 2, 10); // (x, y, длина, угол, глубина)
</script>
</body>
</html>
Как это работает?
-
Используется базовая тригонометрия:
-
x2 = x + length * cos(angle)
-
y2 = y - length * sin(angle)
-
На каждом шаге длина ветви уменьшается (умножается на 0.7).
- Угол разветвления ±30° (π/6 радиан).
- Рекурсия повторяется, пока не достигнута глубина 0.
Пример 2: Кривая Коха
Кривая Коха — классический математический фрактал. Строится так:
- Берём прямой отрезок.
- Делим его на три части.
- Среднюю часть заменяем "зубцом" — равносторонним треугольником.
- Повторяем процесс для каждого отрезка.
Полный код с комментариями:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Кривая Коха</title>
</head>
<body>
<canvas id="canvas" width="800" height="300" style="border:1px solid #ccc;"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
/**
* Рисует кривую Коха между двумя точками
* @param {number} x1 - начальная координата x
* @param {number} y1 - начальная координата y
* @param {number} x2 - конечная координата x
* @param {number} y2 - конечная координата y
* @param {number} depth - уровень рекурсии
*/
function drawKoch(x1, y1, x2, y2, depth) {
if (depth === 0) {
// Базовый случай: рисуем прямой отрезок
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
} else {
// Вычисляем точки деления отрезка на 3 части
const dx = (x2 - x1) / 3;
const dy = (y2 - y1) / 3;
const xA = x1 + dx;
const yA = y1 + dy;
const xB = x1 + 2 * dx;
const yB = y1 + 2 * dy;
// Координаты "пиковой" точки (вершины треугольника)
const angle = Math.PI / 3; // 60°
const xC = xA + (dx * Math.cos(angle) - dy * Math.sin(angle));
const yC = yA + (dx * Math.sin(angle) + dy * Math.cos(angle));
// Рекурсивно рисуем 4 отрезка
drawKoch(x1, y1, xA, yA, depth - 1); // левая часть
drawKoch(xA, yA, xC, yC, depth - 1); // левая сторона треугольника
drawKoch(xC, yC, xB, yB, depth - 1); // правая сторона треугольника
drawKoch(xB, yB, x2, y2, depth - 1); // правая часть
}
}
ctx.strokeStyle = 'blue';
ctx.lineWidth = 1;
// Рисуем одну сторону кривой Коха
drawKoch(100, 150, 700, 150, 4); // (x1, y1, x2, y2, глубина)
</script>
</body>
</html>
Как это работает?
- Делим отрезок на три части: A, B.
- На месте средней части создаём равносторонний треугольник (60° угол).
- Используем формулы поворота вектора на угол:
js
* Строим 4 новых отрезка: начало - A, A - C, C - B, B - конец.
x = x * cos(θ) - y * sin(θ)
y = x * sin(θ) + y * cos(θ)
Фракталы — удивительные объекты, которые можно легко визуализировать в браузере с помощью HTML5 Canvas и JavaScript.
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.