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

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

Что такое фрактал и как его нарисовать на 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: Кривая Коха

    Кривая Коха — классический математический фрактал. Строится так:

    1. Берём прямой отрезок.
    2. Делим его на три части.
    3. Среднюю часть заменяем «зубцом» — равносторонним треугольником.
    4. Повторяем процесс для каждого отрезка.

    Полный код с комментариями:

    <!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

      x = x * cos(θ) - y * sin(θ)

      y = x * sin(θ) + y * cos(θ)

    * Строим 4 новых отрезка: начало — A, A — C, C — B, B — конец.

    Фракталы — удивительные объекты, которые можно легко визуализировать в браузере с помощью HTML5 Canvas и JavaScript.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий