«Пишем симулятор черной дыры на RFO BASIC: как визуализировать ОТО без сложных формул»

В интернете можно найти множество статей о гравитационных эффектах: от черных дыр и горизонта событий до гравитационного линзирования. Мне стало интересно написать собственную программу-симулятор, которая с помощью несложного математического аппарата визуализирует эти явления на графике.
В основу алгоритма я заложил постулат о постоянстве скорости света и вывод Общей теории относительности (ОТО) о гравитационном замедлении времени. Симуляция рассчитана для двумерного пространства и строит траектории фотонов вблизи невращающейся черной дыры. Ниже представлен скриншот работы программы, после чего я поделюсь ее листингом и дам подробные пояснения к коду.

Разбор результатов: что мы видим на экране?
Даже простая двухмерная симуляция на базовых уравнениях отлично демонстрирует ключевые эффекты Общей теории относительности, которые обычно рисуют в учебниках. Давайте разберем траектории лучей, которые получились в программе:
Серые лучи (Дальняя зона): Фотоны, которые проходят на большом расстоянии от черной дыры, лишь слегка искривляют свой путь. Это классическое гравитационное линзирование. Черная дыра работает как космическая линза, искажая свет от фонового источника.
Оранжевый луч (Касательная траектория): Этот луч проходит достаточно близко к массивной точке. Гравитация сильно меняет его направление, «загибая» траекторию почти на 90 градусов, но фотону все же удается вырваться из гравитационного плена и улететь вглубь космоса.
Желтый луч (Фотонная сфера): Это самая интересная граница. Обратите внимание, как желтый луч делает почти полный оборот вокруг черной дыры. В физике эта область называется фотонной сферой (или фотонной оболочкой). Если запустить фотон по идеальной касательной на этом расстоянии, он теоретически должен остаться летать по круговой орбите бесконечно долго.
Интересный нюанс симуляции: Желтый луч изначально шел по стабильной круговой траектории и успел сделать целых два оборота вокруг черной дыры. Однако в итоге он все равно упал под горизонт событий. Это произошло из-за накопления ошибок при округлении чисел с плавающей точкой в процессе пошаговых вычислений. В реальном коде шаг интегрирования
dtконечен, и со временем эта микроскопическая погрешность сбивает фотон с идеальной математической орбиты.
Лучи, уходящие внутрь (Горизонт событий): Фотоны, летящие еще ближе к центру, безвозвратно затягиваются гравитацией. В симуляции наглядно видно, как их шаги (
dxиdy) становятся всё меньше и меньше из-за коэффициента замедления времениktm. Для нас, как внешних наблюдателей, они бесконечно долго приближаются к сингулярности, застывая на пороге горизонта событий.
Координатная сетка пространства
Отдельно стоит обратить внимание на сетку точек в фоновом режиме. Белые точки показывают идеальное плоское пространство (где нет гравитации), а голубые — то, как метрика сжимается и деформируется вблизи массы. Симулятор наглядно доказывает: чтобы описать движение света, не нужно придумывать «магнитные» или неведомые силы притяжения. Достаточно просто позволить свету лететь по прямой с постоянной скоростью в пространстве, где сама геометрия и ход времени искажены массивным телом.
Листинг программы (RFO BASIC)
REM ===================================================
REM Симулятор траекторий фотонов вблизи Черной Дыры
REM Язык: RFO BASIC (Android)
REM ===================================================
DIM xycxcy[780,4] % Массив для хранения координат и направления лучей
GR.OPEN 255, 0, 0, 0, 1, 1
GR.SCREEN w, h
scl = 1 % Масштабирование графики
w = w / scl
h = h / scl
GR.SCALE scl, scl
! Параметры черной дыры (в центре координат)
star_x = 0
star_y = 0
Massa = 2000 % Гравитационная масса
! Параметры пространства и сетки
x_min = -500 : x_max = 500
y_min = -500 : y_max = 500
net = 100 % Шаг координатной сетки
! Физические константы симуляции
c = 35 % Условная скорость света
dt = 0.1 % Шаг интегрирования по времени
! Отрисовка гравитацией сетки пространства
GOSUB setka
! Начальные коодинаты фотонов, отрисовка источника света
xlight = 92.267471
ylight = 700
GR.COLOR 255, 255, 255, 0, 1
GR.CIRCLE start, xlight + w/2, ylight + h/2, 3
GR.RENDER
! Инициализация пучка фотонов (развертка по углам)
FOR alfa = 1 TO 360 STEP 1
xycxcy[alfa,1] = xlight
xycxcy[alfa,2] = ylight
xycxcy[alfa,3] = COS(TORADIANS(alfa))
xycxcy[alfa,4] = SIN(TORADIANS(alfa))
NEXT alfa
! Отрисовка рамки индикатора процесса
GR.COLOR 255, 255, 0, 255, 0
GR.RECT n, 185, 1700, 1015,1730
! --- Главный цикл симуляции (продвижение во времени) ---
FOR n = 0 TO 1000 STEP 1
t = n / 10 % Координатное время (внешнего наблюдателя)
FOR alfa = 178 TO 360 STEP 1 % Просчитываем сектор лучей, летящих вверх
x = xycxcy[alfa,1]
y = xycxcy[alfa,2]
c_x = xycxcy[alfa,3]
c_y = xycxcy[alfa,4]
! Расстояние до сингулярности (с защитой от деления на ноль)
r = SQR((star_x - x)^2 + (star_y - y)^2) + 1e-16
! Расчет гравитационного потенциала
acce_ = Massa / (r^2 + 1e-16)
! Коэффициент замедления времени (Метрика)
ktm = 1 - acce_
! Вектор направления к центру гравитации
acce_x = (star_x - x) / r * acce_
acce_y = (star_y - y) / r * acce_
! Изменение единичного вектора направления фотона (искривление пути)
c_x = c_x + acce_x * dt
c_y = c_y + acce_y * dt
! Нормализация единичного вектора направления(скорость света локально постоянна)
l = SQR(c_x * c_x + c_y * c_y)
c_x = c_x / l
c_y = c_y / l
! Расчет перемещения с учетом замедления времени (ktm)
dx = c * c_x * dt * ktm
dy = c * c_y * dt * ktm
x = x + dx
y = y + dy
! Рисуем обычный фотонный луч (серый цвет)
GR.COLOR 255, 155, 155, 155, 1
GR.CIRCLE light2, xycxcy[alfa,1] + w/2, xycxcy[alfa,2] + h/2, 1
! Подсветка критических траекторий
! 1. Зеленый луч: фотон прямо направленый на черную дыру
IF alfa = 263 THEN
GR.COLOR 255, 0, 255, 0, 1
GR.CIRCLE green, xycxcy[alfa,1] + w/2, xycxcy[alfa,2] + h/2, 2
IF n > 0 THEN tau = tau + dt * ktm % Собственное время фотона
ENDIF
! 2. Желтый луч: фотон попавший в захват черной дыры
IF alfa = 276 THEN
GR.COLOR 255, 255, 255, 0, 1
GR.CIRCLE yellow, xycxcy[alfa,1] + w/2, xycxcy[alfa,2] + h/2, 2
rf = SQR((star_x - x)^2 + (star_y - y)^2)
ENDIF
! 3. Оранжевый луч: фотон ушедший при минимальном расстоянии
IF alfa = 277 THEN
GR.COLOR 255, 255, 155, 0, 1
GR.CIRCLE light2, xycxcy[alfa,1] + w/2, xycxcy[alfa,2] + h/2, 2
ENDIF
! Сохраняем обновленные координаты для следующего шага
xycxcy[alfa,1] = x
xycxcy[alfa,2] = y
xycxcy[alfa,3] = c_x
xycxcy[alfa,4] = c_y
NEXT alfa
GR.RENDER
! Индикатор прогресса симуляции внизу экрана
GR.COLOR 255, 255, 0, 255, 0
GR.RECT nn, 185 + n, 1700, 185 + n, 1730
NEXT n
GR.RENDER
! Задержка графического экрана
DO
UNTIL 0
GR.CLOSE
END
REM ===================================================
REM ПОДПРОГРАММА: Построение гравитационной сетки
REM ===================================================
setka:
FOR x = x_min TO x_max STEP net
FOR y = y_min TO y_max STEP net
! Базовая плоская сетка (белые точки)
GR.COLOR 255, 255, 255, 255, 0
GR.CIRCLE tck, x + w/2, y + h/2, 5
! Вычисление смещения ячеек пространства из-за гравитации
r = SQR((star_x - x)^2 + (star_y - y)^2) + 1e-16
! Эффективный потенциал
acce_ = Massa / (r^2 + 1e-16)
acce_x = (star_x - x) * acce_
acce_y = (star_y - y) * acce_
! Рисуем искривленную сетку (голубые точки)
GR.COLOR 255, 0, 220, 220, 1
GR.CIRCLE tck, acce_x + x + w/2, acce_y + y + h/2, 3
NEXT y
NEXT x
RETURN
##Как запустить эту программу самостоятельно? Если вы хотите вживую увидеть движение лучей и поэкспериментировать с массой или координатами, у вас есть два простых пути:
Запустить в оригинале: Скачайте интерпретатор RFO BASIC. Его актуальные версии можно найти на GitHub или на официальном сайте разработчика (mugoino.free.fr/rfo-basic/). Программа написана для Android, так что симуляцию можно запустить прямо на телефоне.
Запустить прямо в браузере: Если не хочется ничего устанавливать, скопируйте этот код, отправьте его любому доступному ИИ (например, тому же Gemini) и попросите: «Переведи этот код с BASIC на JavaScript и оформи в виде одной HTML- страницы. Прими во внимание % отмечает начало комментария после кода, ! комментарий с начала строки. Уменьши картинку. Увеличь резкость изображения». Можете попросить сделать слайдеры. Полученный файл можно сохранить на компьютере с расширением html и открыть в любом современном браузере (например, в том же Google Chrome). Вы увидите точно такую же графику симуляции!
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.