Документация Engee
Notebook

Спираль Фибоначчи

В этом примере мы разберем, как пользоваться интерактивными скриптами, чтобы удобно сравнивать результаты работы разных моделей – графических и заданных в виде текстовой программы.

Мы построим графическую модель, порождающую точки на спирали Фибоначчи, а затем сравним полученный график с результатом расчета модели золотой спирали.

Изучаемый объект

Спираль Фибоначчи является аппроксимацией золотой спирали. Ее описание дал Леонардо Пизанский (прозванный Фибоначчи) около 1202 г. Она задана при помощи кусочно-линейной кривой, состоящей из четвертей окружностей. Радиус каждой четверти окружности задается рекуррентным соотношением, которое образует знаменитую последовательность Фибоначчи:

где .

(первые два термина 0, 1 обычно отбрасываются, спираль строится сразу с третьего термина: 1, 2, 3, 5, 7...)

Центр каждой окружности подбирается таким образом, чтобы спираль оставалась гладкой. Точки центра каждой окружности можно получить из модели fibonacci_spiral_model.engee (сигналы cx и cy) наравне с их радиусами (сигналы r). По выходным сигналам x и y мы будем строить график спирали Фибоначчи.

Общий вид модели представлен ниже:

image.png

Золотая спираль

Золотая спираль определена на всей числовой оси при помощи одной экспоненциальной функции. Эту функцию одинаково просто задать как при помощи математического выражения, так и при помощи графической модели. Речь идет о логарифмической спирали, радикс которой, за каждую половину оборота , увеличивается на значение . Здесь – число, обратное золотому сечению .

Нам придется усложнить обычное уравнение логарифмической спирали . Дело в том, что точка сходимости спирали Фибоначчи находится не в начале координат и зависит от размеров прямоугольника, в который вписана спираль Фибоначчи. Для совпадения обеих спиралей нужно также ввести в уравнение золотой спирали ненулевой угол начального поворота .

За выводом формулы золотой спирали, максимально совпадающей со спиралью Фибоначчи, лучше обратиться к публикации [1]. Мы же здесь приведем лишь финальную формулу золотой спирали в полярных координатах:

где – ряд координат точек на спирали в полярной системе координатах, – ширина прямоугольника, в который вписана спираль Фибоначчи.

Запуск модели

Запустим модель fibonacci_spiral_model.engee и проанализируем результаты.

In [ ]:
modelName = "fibonacci_spiral_model";
model = modelName in [m.name for m in engee.get_all_models()] ? engee.open( modelName ) : engee.load( "$(@__DIR__)/$(modelName).engee");

Эта конструкция позволила нам проверить, была ли модель загружена и открыта пользователем (тогда нам нужна команда open), или ее нужно загрузить при помощи команды load.

Запустить модель очень просто:

In [ ]:
s = engee.run( modelName, verbose=false )
Out[0]:
SimulationResult(
    run_id => 4,
    "x" => WorkspaceArray{Float64}("fibonacci_spiral_model/x")
,
    "r" => WorkspaceArray{Int64}("fibonacci_spiral_model/r")
,
    "y" => WorkspaceArray{Float64}("fibonacci_spiral_model/y")

)

Выходной объект s содержит таблицы с теми сигналами, которые в модели отмечены как "логируемые" (при помощи пиктограммы ).

Анализ результатов

Выберем окружение для отрисовки графиков.

In [ ]:
gr() # Статичные графики небольшого размера
#plotly() # Интерактивные графики по ширине экрана
Out[0]:
Plots.GRBackend()

Визуализируем ряд чисел Фибоначчи: сигнал r. Этот вектор содержит довольно мало точек, потому что модели, порождающая их, имеет низкую частоту дискретизации.

In [ ]:
plot( s["r"].time, s["r"].value, label="Ряд Фибоначчи", st=:stem )

# Зададим собственные подписи для шкалы X
plot!( xticks=( range( minimum(s["r"].time), maximum(s["r"].time), step=1),
           Int.(range( minimum(s["r"].time), maximum(s["r"].time), step=1))) )
Out[0]:
No description has been provided for this image

Построение золотой спирали

Как мы обсуждали, чтобы построить золотую спираль, совпадающую со спиралью Фибоначчи, нам сперва нужно получить несколько параметров из уже построенной спирали.

In [ ]:
theta = range( -0.8*pi, 12*pi, step=0.01); # Область определения золотой спирали

λ = (sqrt(5)-1)/2; # Число, обратное золотому сечению

# Размеры прямоугольника, в который вписана спираль Фибоначчи
a = maximum(s["x"].value) - minimum(s["x"].value)
b = maximum(s["y"].value) - minimum(s["y"].value)

# Координаты центра спирали Фибоначчи
# - в системе координат этого прямоугольника)
x = (1 - λ)/(2 - λ) * a
y = (1 - λ)/(2 - λ) * b
# - в системе координат графика
sx = minimum(s["x"].value) + x;
sy = maximum(s["y"].value) - y; # (учтем, что ось y направлена вверх)

# Угол поворота золотой спирали относительно спирали Фибоначчи
α = atan( 2*λ - 1 );

Теперь можно рассчитать координаты точек, лежащих на золотой спирали

In [ ]:
# Точки золотой спирали в полярной системе координат
R = @. (a/(2 - λ)) * sqrt(1 + λ^6) * λ^((2/pi)*(theta+α))
# Точки золотой спирали в декартовой системе координат
x,y =  R .* cos.( theta ) .+ sx, R .* sin.( theta ) .+ sy;

Осталось вывести оба графика для визуального сравнения.

In [ ]:
plot( s["x"].value, s["y"].value, lc=:skyblue, aspect_ratio=:equal, lw=4, label="Спираль Фибоначчи" )
plot!( x, y, lc=:black, ls=:dash, label="Золотая спираль", legend=:topleft )
Out[0]:
No description has been provided for this image

Очевидно, что модели довольно хорошо совпадают.

Выводы

Мы использовали базовые блоки Engee, чтобы построить математическую модель, которая аппроксимирует золотую спираль. Затем, используя команды программного управления, мы визуализировали несколько сигналов и сравнили полученный результат с уравнением золотой спирали.

Ссылка:

[1] Duan J. S. Shrinkage points of golden rectangle, Fibonacci spirals, and golden spirals //Discrete Dynamics in Nature and Society. – 2019. – Т. 2019. – С. 1-6.