Нові симуляції
Мережа нейронів — імпульсна нейронна мережа Leaky Integrate-and-Fire
Симуляція на Canvas 2D з N LIF-нейронами з інтегруванням Ейлера при dt = 1 мс. Кожен нейрон має налаштовувану провідність витоку, поріг, потенціал скидання та рефрактерний період. K випадкових збудливих і гальмівних синапсів на нейрон. Показує теплову карту напруги, прокручувану растрову діаграму спайків і живу статистику частоти спрацьовування/синхронності. П'ять пресетів: збалансований, високий вхід, E-домінантний, I-домінантний та осциляторний.
Ріст клітин і морфогенез — поділ, упаковка на основі сил і візерунки Грея-Скотта
Упаковка клітин на основі сил з O(n) просторовим хешуванням сітки для сил відштовхування, адгезії та межі. Пов'язана сітка 80×60 реакції-дифузії Грея-Скотта керує формуванням візерунка, що визначає долю клітини. Кольорові режими: доля, вік і розмір. До 600 клітин; поділ активується, коли радіус перевищує поріг.
Гіроїд — потрійно періодичні мінімальні поверхні через маршуючі куби
Рендеринг 3D TPMS у реальному часі, використовуючи повну 256-варіантну таблицю пошуку маршуючих кубів Борка. Чотири поверхні: гіроїд, Шварц P, алмаз і Неовіус. Three.js r160 з ESM importmap та OrbitControls. Керування ізозначенням, роздільною здатністю, укладанням, перемикачем каркасного вигляду та швидкістю автообертання.
Генеративне місто — процедурний міський краєвид з видом зверху
Рекурсивне розбиття кварталів з тремтінням генерує повне місто за мілісекунди. Зони — житлова, комерційна, парк і вода — слідують градієнту густини від центру міста до передмість. Видовжені високі будівлі скупчуються в центрі. Випадковість LCG із зерном для відтворюваних результатів. Чотири візуальні теми: ніч, день, кіберпанк і захід. Експорт як PNG.
Обчислювальна фотографія — ASCII, мозаїка, штрихування та дизеринг
Чотири ефекти обробки зображень, реалізовані з getImageData: ASCII-арт (сітка символів, відображена за яскравістю), фотомозаїка (усереднення кольору плитки), штрихування диском Пуассона та дизеринг з дифузією помилок Флойда-Стейнберга. Завантажте будь-яке зображення чи оберіть з чотирьох вбудованих джерел. Збережіть результат як PNG.
🧠 Мережа нейронів — динаміка Leaky Integrate-and-Fire
Модель LIF
Нейрон Leaky Integrate-and-Fire (LIF) — робоча конячка обчислювальної нейронауки. Попри свою простоту, він відтворює основні риси реальних нейронів: інтеграцію синаптичних входів, спайк перетину порогу та підпорогове загасання напруги назад до спокою. Мембранний потенціал V кожного нейрона підпорядковується:
τ_m · dV/dt = -(V - V_rest) + R · I(t)
де:
τ_m = мембранна часова стала (типово 10–20 мс)
V_rest = потенціал спокою (−65 мВ)
R = мембранний опір
I(t) = загальний синаптичний струм у момент t
Правило спайка:
якщо V ≥ V_thresh:
записати спайк; V ← V_reset; увійти в рефрактерний період на t_ref мс
Симуляція дискретизує це прямим методом Ейлера при dt = 1 мс — достатньо грубо, щоб працювати в реальному часі, але достатньо точно, щоб точно захоплювати міжспайкові інтервали. При τ_m = 10 мс вільне загасання за крок становить exp(−dt/τ_m) ≈ 0.905, тож нейрон, що не отримує вхідного сигналу, втрачає близько 9.5% своєї надлишкової напруги щомілісекунди.
Синаптична модель і баланс E/I
Кожен спайк від нейрона j доставляє імпульс струму нейрону i після фіксованої синаптичної затримки dij (1-5 мс). Струм загасає експоненційно з синаптичною часовою сталою τsyn:
I_syn(t) = w_ij · exp(-(t - t_spike - d_ij) / τ_syn) [для t > t_spike + d_ij]
Збудливий синапс: w_ij > 0 (AMPA-подібний, τ_syn ≈ 5 мс)
Гальмівний синапс: w_ij < 0 (GABA-подібний, τ_syn ≈ 10 мс)
Співвідношення E/I: 80% збудливих нейронів, 20% гальмівних (закон Дейла)
Баланс E/I критичний. Коли переважає збудження, мережа входить у стан безконтрольного спрацьовування (епілептиформні спалахи). Коли переважає гальмування, активність згасає. Збалансований пресет (приблизно рівний загальний збудливий і гальмівний рушій) дає асинхронний нерегулярний (AI) стан, що нагадує кору головного мозку під час активного неспання.
Теплова карта напруги й растрова діаграма спайків
Ліва панель рендерить 2D теплову карту, де кожен піксель відповідає нейрону (розкладеному в сітку), забарвлену за мембранною напругою: темно-синя при V_rest, переходячи через блакитну й жовту до яскраво-білої при порозі. Права панель показує прокручувану растрову діаграму спайків — кожна точка є одним спайком одного нейрона, нанесеним у момент виникнення. Растр дозволяє миттєву візуальну діагностику стану мережі: розріджені випадкові точки вказують на AI-стан, горизонтальні смуги синхронних точок вказують на осциляторну чи вибухову активність.
Статистика синхронності й частоти
Дві живі статистики обчислюються кожен кадр. Частота спрацьовування популяції r(t) — кількість спайків за останні 50 мс, поділена на N × 0.050 с, даючи частоту в Гц. Синхронність вимірюється як коефіцієнт варіації міжспайкового інтервалу (CVISI), усереднений по нейронах: CV = σISI / μISI. CV ≈ 1 вказує на пуассонівське (AI) спрацьовування; CV ≪ 1 — регулярне (годинникоподібне); CV ≫ 1 вказує на вибухову активність. Осциляторний пресет заганяє мережу в ~40 Гц гамма-ритм, видимий як ритмічні колонки на растрі та CV ≈ 0.3.
🦠 Ріст клітин і морфогенез — поділ, упаковка та формування візерунка
Упаковка клітин на основі сил
Клітини моделюються як м'які диски з позицією xi і радіусом ri. На кожному кроці часу на кожну клітину діють три сили:
F_push(i,j) = k_push · max(0, r_i + r_j - |x_i - x_j|) · n̂_ij // відштовхування перекриття
F_adhesion(i,j) = k_adh · max(0, |x_i - x_j| - (r_i+r_j+d_adh)) · n̂_ij // короткодіюче притягання
F_boundary(i) = k_wall · max(0, r_i - dist_to_boundary) · n̂_wall // м'яка стінка контейнера
Чисто: x_i += (ΣF) · dt / ζ (перезагашена; без інерції)
Просторова сітка прискорює пошук сусідів до O(n) шляхом хешування клітин у відра сітки розміром 2 r_max. Тільки клітини в одному чи сусідньому відрі потребують оцінки сили — це утримує симуляцію на 60 fps навіть поблизу межі в 600 клітин.
Реакція-дифузія Грея-Скотта
Паралельно безперервна сітка 80×60 еволюціонує за рівняннями Грея-Скотта для двох хімічних видів U та V:
∂U/∂t = D_U · ∇²U - U·V² + f·(1 - U)
∂V/∂t = D_V · ∇²V + U·V² - (f + k)·V
Типові параметри для візерунка плям:
D_U = 0.16, D_V = 0.08, f = 0.035, k = 0.065
Лапласіан (5-точковий шаблон, періодичні межі):
∇²U[i,j] = U[i-1,j] + U[i+1,j] + U[i,j-1] + U[i,j+1] - 4·U[i,j]
Швидкість подачі f і швидкість знищення k визначають, який візерунок Тюрінга виникає: плями, смуги, лабіринтоподібні структури чи просторово-часовий хаос. Симуляція відображає позиції клітин на безперервну сітку, щоб вибрати локальну концентрацію V, яка керує долею клітини: висока V → спеціалізована (диференційована) доля; низька V → стовбуроподібна.
Поділ клітини та кольорові режими
Клітина росте зі сталою швидкістю dr/dt = growth_rate. Коли r > r_divide, вона ділиться на дві дочірні клітини під ±45° від випадкової орієнтації, кожна з r = r_divide / √2 (зберігаючи площу). Подія поділу генерує короткодіючий сплеск тиску, що поширюється по колонії через систему сил, створюючи характерну динаміку упаковки клітин, що спостерігається в тканинах, що ростуть.
- Режим долі — колір кодує концентрацію V Грея-Скотта, вибрану в позиції клітини на сітці. Градієнти морфогену дають просторово когерентні кольорові домени.
- Режим віку — колір кодує номер покоління клітини (час з моменту останнього поділу), від молодого (блакитний) до старого (пурпуровий).
- Режим розміру — колір кодує поточний радіус відносно порогу поділу, показуючи, які клітини ось-ось поділяться (яскраво-білий).
💠 Гіроїд — потрійно періодичні мінімальні поверхні
Що таке TPMS?
Потрійно періодична мінімальна поверхня (TPMS) — це поверхня, періодична в усіх трьох просторових напрямках і з нульовою середньою кривизною в кожній точці (H = 0, визначальна властивість мінімальної поверхні). Природа виробляє ці структури спонтанно: вони з'являються в лусочках крил метеликів, мембранах блок-кополімерів та системах ліпідних бішарів. Гіроїд, зокрема, є біконтинуальною структурою — обидві сторони поверхні утворюють з'єднані лабіринти — що робить його високо цінованим у матеріалознавстві для фільтрації, накопичення енергії та фотонних застосувань.
Рівняння неявної поверхні
Кожна поверхня визначається неявним рівнянням F(x, y, z) = t, де t — ізозначення (за замовчуванням t = 0 дає точну мінімальну поверхню). У масштабованих координатах (u = 2πx/a, v = 2πy/a, w = 2πz/a):
Гіроїд: sin(u)cos(v) + sin(v)cos(w) + sin(w)cos(u) = t
Шварц P: cos(u) + cos(v) + cos(w) = t
Алмаз: sin(u)sin(v)sin(w) + sin(u)cos(v)cos(w)
+ cos(u)sin(v)cos(w) + cos(u)cos(v)sin(w) = t
Неовіус: 3(cos(u)+cos(v)+cos(w)) + 4cos(u)cos(v)cos(w) = t
Гіроїд був відкритий Аланом Шоеном у 1970 році під час дослідження NASA щодо легких структур. На відміну від поверхонь Шварца P та D, він не має прямих ліній чи площин дзеркальної симетрії, надаючи йому хіральний, лабіринтоподібний характер.
Алгоритм маршуючих кубів
Симуляція обчислює F на регулярній сітці N³ вокселів (за замовчуванням N = 48) і витягує ізоповерхню F = t, використовуючи 256-варіантну таблицю пошуку маршуючих кубів Борка. Кожному кубу вокселя призначається 8-бітний індекс (по одному біту на кут, встановлений, якщо F > t) — індекс шукає одну з 256 конфігурацій трикутників, даючи до 5 трикутників на куб. Вершини розміщуються на ребрах куба лінійною інтерполяцією:
// Для ребра від вершини A (значення fA) до вершини B (значення fB):
t_lerp = (isovalue - fA) / (fB - fA)
вершина = A + t_lerp · (B - A)
Загальна кількість трикутників: O(N² · площа поверхні у вокселях)
Для N=48, укладання=1: типово ~80 000–120 000 трикутників
Нормалі вершин обчислюються аналітично з ∇F, а не усередненням нормалей граней — це дає ідеально гладке затінення при будь-якій роздільній здатності. Меш завантажується в Three.js BufferGeometry та рендериться з MeshStandardMaterial під картою середовища, даючи металевий/переливчастий вигляд.
Керування укладанням та ізозначенням
Повзунок укладання повторює одиничну клітину 1-4 рази по кожній осі, демонструючи періодичну природу поверхні. Збільшення ізозначення t зсуває поверхню до однієї сторони біконтинуального розділу: при t = 0 два лабіринти мають однаковий об'єм; при t > 0 один лабіринт зменшується й врешті-решт стискається, переходячи від TPMS до топології пінопласту із закритими клітинами.
🌃 Генеративне місто — процедурний міський краєвид
Рекурсивне розбиття кварталів
Планування міста генерується рекурсивним розбиттям прямокутного полотна. Починаючи з повного прямокутника полотна, алгоритм розділяє його вздовж горизонтальної чи вертикальної осі, додаючи невелике випадкове тремтіння (±10% довжини сторони) до позиції розбиття, щоб уникнути відчуття сітки. Розбиття продовжується, доки ширина чи висота кварталу не впаде нижче мінімального розміру ділянки. Вісь розбиття чергується детерміновано на основі відношення сторін поточного прямокутника: завжди розділяти довгу сторону.
function subdivide(rect, depth):
якщо rect.w < MIN_LOT або rect.h < MIN_LOT: повернути [rect]
axis = rect.w > rect.h ? 'x' : 'y'
split = lerp(0.35, 0.65, lcg_random()) * (axis='x' ? rect.w : rect.h)
[left, right] = split_rect(rect, axis, split + jitter())
повернути subdivide(left, depth+1) + subdivide(right, depth+1)
Це дає нерегулярний, але реалістичний візерунок кварталів, що нагадує органічне зростання міста, а не жорстку декартову сітку.
Зонування та градієнт густини
Кожен листовий квартал отримує зону на основі відстані від центру міста (нормалізованої до [0, 1]):
- Комерційна (d < 0.25) — щільні високі будівлі; прямокутники заповнюють більшу частину кварталу, залишаючи лише вузький проміжок вулиці. Кольори: теплі сірі й аспідно-блакитні.
- Житлова (0.25 ≤ d < 0.65) — менші будівлі з садами. Квартали містять 2-8 контурів будинків зі спільним проміжком двору. Кольори: теплі коричневі.
- Парк (випадкові 12% кварталів середнього кільця) — заповнений штрихованим зеленим візерунком. Дає візуальний простір і реалістичний відкритий простір.
- Вода (суцільні плями в зовнішньому кільці, ~8% площі) — рендериться з анімованими лініями мерехтіння. Річки й озера виникають зі злиття сусідніх водних кварталів.
Висота будівлі кодується яскравістю кольору: вищі будівлі отримують світліше заповнення й білу смугу-«шапку», даючи вигляду зверху неявну 3D-підказку.
Випадковість LCG із зерном для відтворюваності
Уся випадковість проходить через лінійний конгруентний генератор із зерном, заданим користувачем:
// параметри LCG (Numerical Recipes)
a = 1664525; c = 1013904223; m = 2^32
seed = (a * seed + c) % m
random() { seed = ...; повернути seed / m; }
Одне й те саме зерно завжди дає одне й те саме місто. Чотири теми (ніч, день, кіберпанк, захід) змінюють лише кольорову палітру, а не планування — тож можна порівняти, як та сама міська структура виглядає в різний час доби.
🖼️ Обчислювальна фотографія — чотири алгоритми обробки зображень
ASCII-арт через відображення яскравості
Зображення знижується до сітки символів (за замовчуванням 120 стовпців). Середня яскравість кожної клітини L = 0.299R + 0.587G + 0.114B (ITU-R BT.601) відображається на один з 70 символів, відсортованих за візуальною густиною від найтемнішого до найсвітлішого:
charset = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
char_index = floor(L / 255 * (charset.length - 1))
// Рендер шрифтом з фіксованою шириною; колір з оригінального пікселя для режиму кольорового ASCII
Фотомозаїка через усереднення кольору плитки
Ефект фотомозаїки ділить зображення на прямокутні плитки (розмір налаштовується від 4×4 до 32×32 пікселів) і замінює кожну плитку суцільним заповненням її середнім кольором. Це цифровий еквівалент класичної фотомозаїки, а при великих розмірах плитки він функціонує як фільтр пікселізації/конфіденційності. Усереднення використовує повне сканування всіх пікселів у кожній плитці — а не вибіркове наближення — забезпечуючи точність кольору.
Штрихування диском Пуассона
Штрихування перетворює зображення на набір крапок, чия густина кодує яскравість. Симуляція використовує наближення методом відхилення вибірки: кандидатські позиції крапок обираються рівномірно випадково; крапка розміщується лише якщо локальна яскравість (інвертована, тож темні ділянки отримують більше крапок) перевищує поріг. Мінімальна відстань між крапками забезпечує розподіл диска Пуассона, запобігаючи скупченню:
для кожного кандидата (x, y):
L = luminance(x, y)
density = 1 - L/255 // темний піксель → висока густина
якщо random() < density і no_dot_within_r(x, y, r_min):
розмістити крапку в (x, y)
Дизеринг з дифузією помилок Флойда-Стейнберга
Класичний дизеринг Флойда-Стейнберга дає 1-бітне (чорно-біле) представлення, що перцептивно відповідає безперервному оригіналу. Алгоритм сканує пікселі зліва направо, зверху вниз. Кожен піксель квантується до чорного (0) чи білого (255); помилка квантування розподіляється між чотирма сусідами:
error = original_pixel - quantised_pixel
pixel[x+1][y ] += error × 7/16
pixel[x-1][y+1] += error × 3/16
pixel[x ][y+1] += error × 5/16
pixel[x+1][y+1] += error × 1/16
Помилка поширюється вперед і вниз, тож темні ділянки накопичують позитивну помилку (роблячи пізніші пікселі більш схильними округлятися до білого) і навпаки. Результат — напівтоновий візерунок з високочастотним шумом дизерингу, який на нормальній відстані перегляду виглядає як сірий тон, що відповідає оригінальній яскравості. Дизеринг Флойда-Стейнберга був опублікований у 1976 році й залишається стандартним алгоритмом у редакторах зображень і принтерах по всьому світу.
Що далі
Хвиля 63 переходить до гідродинаміки, комбінаторної математики та оптики. Далі: повзуча течія Стокса з демонстрацією оборотності, коефіцієнти упаковки сфер у 2D та 3D, криві Гільберта і Пеано, що заповнюють простір, спіраль Улама простих чисел, максимальний потік Едмондса-Карпа з анімованими доповнювальними шляхами та трасувальник променів крижаного ореолу методом Монте-Карло, що відтворює ореоли 22° та бічні сонця.