Що таке фрактал?
Фрактал — це візерунок, який виглядає однаково, хоч би як близько ти його наближав. Природа сповнена ними — берегові лінії, сніжинки, папороті, кровоносні судини й галактики мають фрактальну структуру. Математика здатна породжувати нескінченно деталізовані фрактальні форми лише кількома рядками коду.
Самоподібність
Визначальна властивість фрактала — це самоподібність: кожна частина візерунка виглядає як менша копія цілого. Якщо наблизити фрактальне зображення, ти й далі бачитимеш ту саму деталь, повторену на дедалі менших масштабах — складність ніколи не вичерпується.
Математики кажуть, що фрактал є точно самоподібним, якщо кожна частина є ідеальною масштабованою копією, або статистично самоподібним, якщо статистичні властивості однакові на всіх масштабах (як-от берегова лінія Британії).
Класичні приклади фракталів
Трикутник Серпінського
Почни з рівностороннього трикутника. Видали центральний трикутник (з'єднай середини кожної сторони). Повтори те саме з кожним із трьох трикутників, що лишилися. Продовжуй нескінченно — отримаєш трикутник Серпінського. Він має нульову площу, але нескінченний периметр (принаймні в теорії).
Сніжинка Коха
Почни з рівностороннього трикутника. Заміни середню третину кожної сторони меншим рівностороннім трикутником, спрямованим назовні. На кожному кроці ти додаєш більше шпичок. Периметр зростає без межі, але площа збігається до скінченного значення (8/5 від площі початкового трикутника).
Множина Кантора
Почни з відрізка прямої. Видали середню третину. Видали середню третину кожного з частин, що лишилися. Повтори. У результаті отримаєш нескінченну множину точок, яка має нульову довжину — але все одно містить нескінченно багато точок.
Множина Мандельброта
Найвідоміший фрактал — це множина Мандельброта, відкрита Бенуа Мандельбротом у 1980-х роках. Вона визначається простим правилом, застосованим до комплексних чисел:
z₀ = 0, zₙ₊₁ = zₙ² + c
Для кожної точки c на комплексній площині багаторазово застосовуй формулу. Якщо значення |z| залишається обмеженим (ніколи не зростає до нескінченності), то c належить до множини Мандельброта (зафарбовується чорним). Якщо ж воно тікає до нескінченності, зафарбуй c залежно від того, як швидко це сталося. У результаті утворюється нескінченно складна межа, що відкриває нові форми на кожному рівні наближення.
Фрактальна розмірність
Звичайна геометрія використовує цілочислові розмірності: точка — 0D, лінія — 1D, поверхня — 2D, тіло — 3D. Фрактали ж можуть мати дробові розмірності!
Розмірність Гаусдорфа D самоподібного фрактала, що складається з N копій, масштабованих із коефіцієнтом r, дорівнює:
D = log(N) / log(1/r)
- Трикутник Серпінського: 3 копії в масштабі 1/2 → D = log3/log2 ≈ 1,585
- Сторона сніжинки Коха: 4 копії в масштабі 1/3 → D = log4/log3 ≈ 1,262
- Берегова лінія Британії: D ≈ 1,25
- Бронхіальне дерево легень людини: D ≈ 2,97
Фрактали в природі
Фракталоподібні структури з'являються по всьому природному світу, бо вони ефективно розв'язують інженерні задачі:
- Легені: Розгалужені бронхи максимізують площу поверхні для газообміну в компактному об'ємі.
- Кровоносні судини: Фрактальне розгалуження ефективно доставляє кров до кожної клітини.
- Сніжинки: Молекули води самоорганізуються за обмежень симетрії, утворюючи шестипроменеві фрактальні кристали.
- Папороті: Кожна гілка є меншою копією цілої рослини — проста генетична програма породжує складну структуру.
- Берегові лінії та гори: Ерозія на всіх масштабах утворює самоподібний рельєф.
- Галактики: Великомасштабна структура Всесвіту утворює фракталоподібні нитки й порожнечі.
Побудуй фрактальне дерево за 20 рядків
Фрактальне дерево — один із найпростіших фракталів для програмування. Кожна гілка розщеплюється на дві дочірні під певним кутом — те саме правило застосовується рекурсивно:
function branch(ctx, x, y, len, angle, depth) {
if (depth === 0) return;
// Обчислюємо кінцеву точку цієї гілки
const x2 = x + len * Math.cos(angle);
const y2 = y - len * Math.sin(angle); // y інвертовано на canvas
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x2, y2);
ctx.stroke();
// Рекурсія: дві дочірні гілки, кожна завдовжки 70%, повернуті на ±25°
branch(ctx, x2, y2, len * 0.7, angle + 0.44, depth - 1);
branch(ctx, x2, y2, len * 0.7, angle - 0.44, depth - 1);
}
// Виклик з depth=11 для детального дерева
branch(ctx, 400, 600, 120, Math.PI / 2, 11);