Одним вечером я решил проверить: что если взять решётку из 10 000 узлов, задать одно правило передачи энергии между соседями — и просто запустить? Никакой теоретической физики из учебника, никакой подготовки. Посмотреть что вырастет само.
Спойлер: за один день появились волновое уравнение, интерференция, фазовый переход, рождение и аннигиляция частиц, и стрела времени. Всё из одного уравнения.
<cut />
Старт: убираем случайность
У меня уже был проект — симуляция квантового поля на тетраэдрах, где узлы случайно осциллировали (Math.random()). Красиво, но мертво. Шум без смысла, без структуры.
Я сделал шаг: заменил случайность на детерминированный закон. Каждый тик поле в каждом узле обновляется по правилу:
// GridField.java private void update() { double[][] newPhi = new double[HEIGHT][WIDTH]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { // Дискретный Лапласиан (4 соседа, торическая топология) int left = (x - 1 + WIDTH) % WIDTH; int right = (x + 1) % WIDTH; int up = (y - 1 + HEIGHT) % HEIGHT; int down = (y + 1) % HEIGHT; double laplacian = phi[y][left] + phi[y][right] + phi[up][x] + phi[down][x] - 4.0 * phi[y][x]; // φ⁴ потенциал: тянет поле к вакуумам ±V double force = -LAMBDA * (phi[y][x] * phi[y][x] - V * V) * phi[y][x]; velocity[y][x] = velocity[y][x] * DAMPING + FLOW_RATE * laplacian + force; newPhi[y][x] = phi[y][x] + velocity[y][x]; } } phi = newPhi; tick++; }
Константы которые управляют всем поведением:
static final int WIDTH = 100; static final int HEIGHT = 100; static final double FLOW_RATE = 0.20; // скорость волны, ОБЯЗАТЕЛЬНО < 0.25 static final double DAMPING = 0.998; // затухание (1.0 = без потерь) static final double V = 300.0; // положение вакуумов ±V static final double LAMBDA = 0.000002; // сила нелинейности φ⁴
Важно: FLOW_RATE < 0.25 — это условие устойчивости Куранта для дискретного волнового уравнения. Выше — поле взрывается в NaN за несколько тиков.
Фаза 1: одно правило → волна и интерференция
Запустил с LAMBDA = 0 (чистое волновое уравнение). Одна точка возбуждения в центре:
// GridMain.java GridField field = new GridField(); field.excite(50, 50, 600.0); field.start(50); // 50ms на тик = ~20 тиков/сек
По экрану пошла идеальная круговая волна. Дошла до края — появилась с другой стороны, потому что решётка замкнута как тор (периодические граничные условия).
Волна вернулась и встретила себя. На экране появились концентрические интерференционные кольца — точно как в двухщелевом опыте Юнга. Только я этого не программировал. Это вышло из Лапласиана.
Два источника:
field.excite(35, 50, 600.0); field.excite(65, 50, 600.0);
Два кольца пересеклись — паттерн интерференции с узлами и пучностями. Принцип Гюйгенса — каждый узел сам становится источником — реализовался автоматически.
Фаза 2: нелинейность → частицы
Чистое волновое уравнение умирает: через тысячу тиков поле превращается в равномерный туман. Тепловая смерть. Второе начало термодинамики не было заложено — оно просто случилось.
Включаю LAMBDA = 0.000002.
Потенциал φ⁴ — это V(arphi) = \lambda(arphi^2 - V^2)^2 — двойная яма. Поле теперь хочет быть либо в +V, либо в −V. Как магнит который намагничен в одну из двух сторон.
После одного клика мышью:
Расходится волна — как раньше
Поле начинает выбирать: здесь домен +V, там домен −V
На границах доменов возникает устойчивая структура — не размывается
Эти границы движутся, сталкиваются, аннигилируют
Детектор "частиц":
// GridField.java public List<int[]> detectParticles() { List<int[]> boundaries = new ArrayList<>(); for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int right = (x + 1) % WIDTH; int down = (y + 1) % HEIGHT; // Граница домена = соседи имеют разные знаки if (phi[y][x] * phi[y][right] < 0 || phi[y][x] * phi[down][x] < 0) { boundaries.add(new int[]{x, y}); } } } return boundaries; }
Счётчик показал: 7 → 222 → 1397 → 9821 частиц. Всегда чётное число — они рождаются парами (топологический заряд сохраняется). Я это не закладывал.
Что я увидел на экране
Tick 58 — одна точка возбуждения, φ⁴ включён. На синем фоне (вакуум −V) появился идеальный золотой круг (домен +V) с чёткой чёрной границей. Как мыльный пузырь. Как другое пространство внутри.

В космологии это называется фазовым переходом при инфляции — пузырь новой фазы вакуума внутри старого. Это есть в учебниках по физике раннего Вселенной. Я не читал про это когда писал код. Оно просто получилось.
Tick 821 — 5297 частиц. Крестообразная структура из доменов — результат возвратных волн с тора, интерферирующих с доменными стенками.

Tick 18 245 — 9821 частица. Максимально хаотичный вакуум. Это квантовый вакуум — не пустота, а кипящее море виртуальных пар которые рождаются и тут же аннигилируют.

Физика которая вышла сама — без намерения
Явление | Где видно | Было запрограммировано? |
|---|---|---|
Волновое уравнение | Концентрические кольца | Нет |
Принцип Гюйгенса | Каждый узел = источник | Нет |
Интерференция | Полосы при двух источниках | Нет |
Торическая топология | Волна возвращается | Да (граничные условия) |
Фазовый переход | Домены ±V | Нет |
Рождение пар | Счётчик чётный | Нет |
Аннигиляция | Счётчик падает | Нет |
Стрела времени | Порядок → хаос | Нет |
Тепловая смерть | Туман через 1000 тиков | Нет |
9 из 10 явлений не программировались. Они вышли из одного уравнения в 15 строк.
Управление
// GridVisualization.java // ЛКМ / drag → +2000 к φ в узле // ПКМ / drag → −1000 к φ в узле @Override public void mousePressed(MouseEvent e) { int x = e.getX() / CELL_SIZE; int y = e.getY() / CELL_SIZE; double amount = SwingUtilities.isRightMouseButton(e) ? -1000.0 : 2000.0; field.excite(x, y, amount); }
Кликаешь левой — создаёшь возбуждение. Правой — убираешь. Можно "потолкать" домен и посмотреть как он движется.
Что дальше
Следующий шаг — атом. Атом это стоячая волна которая замкнулась сама на себе. Для этого нужно второе поле χ, связанное с основным φ через бипотенциал:
V(arphi, \chi) = \lambda(arphi^2 - V^2)^2 - g \cdot arphi^2 \cdot \chi^2
Лёгкое поле χ будет резонировать вокруг тяжёлого φ-сгустка. Выживут только орбиты где умещается целое число длин волн χ. Квантование энергий выйдет само — из геометрии, не из аксиом.
Код
Java 17+, никаких зависимостей кроме стандартного Swing. Gradle сборка. Репозиторий: github.com/malexple/quant
git clone https://github.com/malexple/quant ./gradlew run
Запускаешь. Кликаешь в центр. Смотришь как рождаются и умирают частицы. Занимает минуту.
После этой минуты квантовое поле перестаёт быть абстракцией из учебника.
Написано за один день итеративного эксперимента. Следующая статья — два связанных поля и попытка получить атом.
