Симуляция гравитационных эффектов ОТО на 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, 0, 255, 255, 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

##Как запустить эту программу самостоятельно? Если вы хотите вживую увидеть движение лучей и поэкспериментировать с массой или координатами, у вас есть два простых пути:

  1. Запустить в оригинале: Скачайте интерпретатор RFO BASIC. Его актуальные версии можно найти на GitHub или на официальном сайте разработчика (mugoino.free.fr/rfo‑basic/). Программа написана для Android, так что симуляцию можно запустить прямо на телефоне.

  2. Запустить прямо в браузере: Если не хочется ничего устанавливать, скопируйте этот код, отправьте его любому доступному ИИ (например, тому же Gemini) и попросите: «Переведи этот код с BASIC на JavaScript и оформи в виде одной HTML‑ страницы. Прими во внимание% отмечает начало комментария после кода,! комментарий с начала строки. Уменьши картинку. Увеличь резкость изображения». Можете попросить сделать слайдеры. Полученный файл можно сохранить на компьютере с расширением html и открыть в любом современном браузере (например, в том же Google Chrome). Вы увидите точно такую же графику симуляции!


Комментарии (2)


  1. ksbes
    20.10.2026 08:46

    Оранжевый луч

    Он у вас циановый

    Если запустить фотон по идеальной касательной на этом расстоянии, он теоретически должен остаться летать по круговой орбите бесконечно долго

    Нет, это неустойчивая траектория. Малейшее возмущение и :

    Однако в итоге он все равно упал под горизонт событий.

    Т.е. ошибка там “накопится” в любом случае при любой разностной схеме - луч либо упадёт, либо улетит.


  1. volkovfedor Автор
    20.10.2026 08:46

    Я с вами полностью согласен, характерной особенностью орбиты фотона в фотонной сфере является неустойчивость. В программе, чтобы фотон удержался на орбите даже два витка мне пришлось уточнить координату до 6 знака после запятой, если уточнить до 7, он продержится еще полкруга и сойдет. И так далее. Я хотел сказать, что накопление ошибок при округлении усиливает этот процесс. С цветом я действительно ошибся.