ГоловнаСтаттіФрактали

Множина Мандельброта: Нескінченна Детальність від z² + c

Алгоритм визначення часу виходу, точне обмеження радіусом 2, плавне забарвлення, перевірка кардіоїда та хитрий трюк з теорією збурень для глибоких збільшень.

mysimulator teamОновлено — червень 2026≈ 11 хв читання▶ Відкрити симуляцію

Один рядок арифметики, повторюваний

Мандельбротів множин визначено ітерацією настільки короткою, що вона поміщається в твіті. Візьміть комплексне число c. Почніть з z = 0 та застосовуйте, знову і знову:

z_{n+1} = z_n² + c з z_0 = 0 c є у множині ⟺ послідовність залишається обмеженою назавжди c не є у множині ⟺ послідовність розбігається до нескінченності Це вся визначення. Кожна спіраль, кожен волокно, копія множини, захована в трильйонах зумів глибоко - це наслідок квадратування та додавання. Множина названа на честь Бенуа Мандельброта, який створив перші зображення цього об'єкта в IBM у 1980 році та розпізнав, що він дивився на; основні комплексні динаміки вивчалися П’єром Фату та Гастоном Джулією близько 1918 року, повністю без комп'ютерів.

z_{n+1} = z_n² + c        with z_0 = 0

c is IN the set     ⟺  the sequence stays bounded forever
c is OUT of the set ⟺  the sequence runs away to infinity
жива демонстрація · пов'язана симуляція● LIVE

Алгоритм ухильнення

Ви не можете ітеруватися назавжди, тому вам потрібен тест, який завершується. Він надається невеликим теоремою: якщо |z| коли-небудь перевищує 2, послідовність гарантовано розійдеться та ніколи не повернеться. Причина проста — коли |z| > 2 і |z| ≥ |c|, піднесення до квадрату робить модуль швидше, ніж додавання c може його стримати. Отже, радіус ухилення 2 є точним, а не припущенням.

функція escape(cx, cy, maxIter) { let x = 0, y = 0, x2 = 0, y2 = 0, i = 0; while (x2 + y2 <= 4 && i < maxIter) { // порівняння квадратів: без sqrt y = 2 * x * y + cy; // 3 множення на x = x2 - y2 + cx; // ітерацію, а не 4 x2 = x * x; y2 = y * y; i++; } return i; // i === maxIter → припустити всередині }

Точки, які ніколи не ухиляються, просто вичерпають maxIter і їх фарбують чорним. Це фундаментальна асиметрія рендерингу множини: ухилення доведено, членство — ні. Кожний чорний піксель є здогадком, чий рівень впевненості обмежений вашим лімітом ітерацій — і коли ви збільшуєте масштаб, структурні межі потребують все більше ітерацій для вирішення, що пояснює, чому глибокі масштаби сповіляються навіть за постійної роздільної здатності.

function escape(cx, cy, maxIter) {
  let x = 0, y = 0, x2 = 0, y2 = 0, i = 0;
  while (x2 + y2 <= 4 && i < maxIter) {   // compare squares: no sqrt
    y  = 2 * x * y + cy;                  // 3 multiplications per
    x  = x2 - y2 + cx;                    // iteration, not 4
    x2 = x * x;
    y2 = y * y;
    i++;
  }
  return i;                               // i === maxIter → assume inside
}

Создання гладкості та швидкість

Кольорування на основі сирого цілого числа i дає жорсткі концентричні смуги, оскільки i є функцією кроку. Виправлення полягає у нормалізованому чисельній ітерації, яка інтерполює між смужками за допомогою того, наскільки далеко завершення z перевищило радіус відступу:

// після циклу вийшов з |z|² = x2 + y2 const logZn = Math.log(x2 + y2) / 2; const nu = Math.log(logZn / Math.log(2)) / Math.log(2); const smooth = i + 1 - nu; // реальне число, а не ціле число Використовуйте цю значущу кількість як реальну величину та застосуйте палітру, і смуги розчиняються в безперервній градієнті. Ще дві стандартні пришвидшення мають набагато більший вплив, ніж мікрооптимізація внутрішнього циклу:

внутрішні перевірки Точна алгебраїчна перевірка основної кардіоїди та періоду 2 бульби. Точки всередині їх мають бути в наборі, тому повністю пропустіть ітерацію. Це само по собі видаляє більшість роботи, обмеженої maxIter, у повній перевірці набору. виявлення періодів Обмежений орбіт зрештою циклічно повторюється. Тримайте посилання (Бент / цикл z кожні кілька ітерацій та вийти рано, коли орбіта повертається в межах epsilon від неї — точка є в наборі та немає потреби досягати maxIter. виявлення) Перевірка кардіоїди варта написання, оскільки вона дешева і заощаджує багато роботи:

// after the loop escaped with |z|² = x2 + y2
const logZn = Math.log(x2 + y2) / 2;
const nu    = Math.log(logZn / Math.log(2)) / Math.log(2);
const smooth = i + 1 - nu;                // a real number, not an integer

Що насправді є межею

Всередині сірий і безформний; вся структура знаходиться на межі. Три факти, які варто запам'ятати. По-перше, множина зв’язана — Адріен Дода та Джон Хаббард довели це в 1982 році. Острови, які ви бачите, плаваючі у чорному морі при великому збільшенні, не є островами: вони з'єднані з основним тілом тонкими волокнами, які занадто тонкі для відображення.

По-друге, межа має гаусівську розмірність рівно 2 — Міцухіро Шишікура, 1998 рік — незважаючи на те, що площа її дорівнює нулю. Вона так само складна, як і крива в площині. По-третє, множина приблизно самоподібна: маленькі копії, розкидані вздовж волокон, не є точними масштабованими відтвореннями всієї множини, і кожна з них прикрашена по-різному. Множина Мандельброта є фракталом у сенсі нескінченної деталізації на будь-якому рівні, а не у сенсі точної самоподібності, як трикутник Sierpiński.

Існує також прямий зв’язок із множинами Юли, які використовують той самий ітеративний процес, але фіксують c та змінюють z₀. Множина Мандельброта є точно відображенням того, який c дає зв'язану множину Юли: виберіть c всередині її та відповідна множина Юли буде одним з’єднаним шматком; виберіть один зовні, і множина Юли розпадається на пил Кантора. Кожна точка множини Мандельброта є мініатюрним індексом у різну множину Юли — тому дослідник, який показує обидві сторони поруч, набагато більш інформативний, ніж будь-яка з них окремо.

Плаваюча границя

Якщо збільшити масштаб достатньо сильно, зображення перетворюється на розмитий шум — не тому, що множина втрачає деталі, а тому що подвійна точність вичерпує кількість значущих цифр. 64-бітове число подвійної точності може утримувати приблизно 15–16 десяткових знаків, тому як тільки ширина вашого вікна падає приблизно до 10⁻¹⁵ від початкового, сусідні пікселі округлюються до одного й того ж числа, і зображення стає блочним.

Серйозні рендери глибокого масштабу ухиляються від цього за допомогою теорії збурень: обчислюється одна високоточна опорна орбіта в центрі зору за допомогою арифметики з нескінченною точністю, а всі інші пікселі виражаються як невелике зміщення від цієї опорної орбіти та ітерується зміщення у звичайній подвійній точності. Зміщення залишаються невеликими, тому втрата точності не стає критичною, і потрібно лише одну орбіту обчислювати за допомогою повільної арифметики великих чисел. Додайте апроксимацію для пропуску перших тисяч ітерацій кожної орбіти зміщення, і масштабування набагато далі 10⁻³⁰⁰ стає практичним — таким чином створюються глибокі відео з масштабуванням, які ви бачили. Єдиний ризик – це артефакти: пікселі, чия орбіта проходить занадто близько до нуля відносно опорної, втрачають точність і повинні бути виявлені та перемальовані за допомогою другої опорної.

Часті запитання

Чому радіус уникнення точно дорівнює 2?

Це тому, що коли |z| перевищує 2 (і |z| ≥ |c|), піднесення до квадрату збільшує модуль швидше, ніж додавання c може його повернути назад, тому послідовність гарантовано розбігається до нескінченності. Це доведений прецедент, а не емпіричний поріг — жодна орбіта, яка покидає диск радіусом 2, ніколи не повертається.

Чому мій глибокий зум перетворюється на блоки?

Подвійна точність плаваючого кома містить приблизно 15-16 значущих цифр. Коли візор знаходиться близько до 10⁻¹⁵ від початкової ширини, сусідні пікселі округлюються до одного й того ж координати. Рендерери глибокого зуму уникають цього за допомогою теорії збурень: одна орбіта з використанням произвольної точності плюс невеликі дельти на піксель, які ітеративно обчислюються у подвійній точності.

Чи є множество Мандельброта самосхожим?

Не зовсім. У ньому нескінченна деталізація на кожному масштабі, і воно містить безліч малих копій себе, але ці копії спотворені, і кожна прикрашена по-різному — тому воно не є точно самосхожим так, як це робить, наприклад, трикутник Sierpiński або крива Коха. Його межа має розмірність Гаусдорфа 2, хоча і закриває нульову площу.

Спробуйте наживо

Усе, що вище, працює прямо у вашому браузері — відкрийте Mandelbrot Set Explorer і змінюйте параметри під час роботи. Нічого не встановлюється, нічого не завантажується на сервер, уся модель живе в одній вкладці.

▶ Відкрити симуляцію Mandelbrot Set Explorer

Що ви знайшли?

Додати кроки відтворення (опційно)