斐波那契螺旋¶
在这个示例中,我们将向您展示如何使用交互式脚本来方便地比较不同模型(图形和文本)的结果。
我们将建立一个在_斐波纳契螺旋线_上生成点的图形模型,然后将得到的图形与_金螺旋线_模型的计算结果进行比较。
研究对象¶
斐波那契螺旋是黄金螺旋的近似值。它是由比萨的莱昂纳多(绰号斐波那契)在 1202 年左右描述的。 它是通过由四分之一圆组成的分段线性曲线来定义的。每个四分之一圆的半径$n$ 是由一个递推关系给出的,这个递推关系构成了著名的斐波纳契数列:
$$F_0 = 0, ~ F_1 = 1, ~ F_n = F_{n-1} + F_{n-2}$$
其中$n \geq 2, ~ n \in Z$.
.
(前两个项0、1通常被舍弃,螺旋从第三个项开始:1、2、3、5、7..._)
选择每个圆的中心是为了使螺旋保持平滑。每个圆的中心点可以从模型fibonacci_spiral_model.engee
(信号cx
和cy
)及其半径(信号r
)中获得。我们将利用输出信号x
和y
绘制斐波那契螺旋线。
<br
该模型的全貌如下:
金色螺旋¶
黄金螺旋在整个数字轴上由一个指数函数定义。这个函数既可以用数学表达式定义,也可以用图形模型定义。它是一个对数螺旋,每转半圈$\pi/2$ ,其弧度值就会增加$\lambda = \frac{\sqrt{5}-1}{2} \approx 0.618$ 。这里的$\lambda$ 是黄金分割率的倒数$\varphi \approx 1.618$.
。
我们必须把对数螺旋的通常方程复杂化$r = c \lambda^{(2/\pi)\theta}$ 。斐波那契螺旋线的汇聚点$(s_x, s_y)$ 并不在坐标原点,它取决于斐波那契螺旋线所嵌入的矩形的大小。为了使这两种螺旋线重合,还必须在黄金螺旋线的方程中输入一个非零的初始旋转角$\alpha$ 。
关于与斐波那契螺旋最大程度重合的_黄金螺旋的公式推导,最好参阅出版物 [1]。这里我们只给出极坐标下黄金螺旋的最终公式:
$$r = \frac{a}{2 - \lambda}\sqrt{1 + \lambda^6} \lambda^{\frac{2}{\pi}(\theta + \alpha)}$$
其中$(\theta, r)$ 是极坐标系中螺旋线上的一系列点的坐标,$a$ 是斐波那契螺旋线所刻画的矩形的宽度。
运行模型¶
让我们运行模型fibonacci_spiral_model.engee
并分析结果。
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
命令加载。
运行模型非常简单:
s = engee.run( modelName, verbose=false )
输出对象s
包含在模型中标记为 "记录 "的信号表(使用 ).
分析结果¶
让我们选择一个绘制图表的环境。
using Plots
gr() # Статичные графики небольшого размера
#plotly() # Интерактивные графики по ширине экрана
让我们将一系列斐波那契数字可视化:信号r
。这个向量包含的点很少,因为生成这些点的模型采样率很低。
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))) )
构建黄金螺旋¶
正如我们所讨论的,为了构建一个与斐波那契螺旋相匹配的黄金螺旋,我们首先需要从一个已经构建好的螺旋中获取一些参数。
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 );
现在我们可以计算黄金螺旋上各点的坐标了
# Точки золотой спирали в полярной системе координат
R = @. (a/(2 - λ)) * sqrt(1 + λ^6) * λ^((2/pi)*(theta+α))
# Точки золотой спирали в декартовой системе координат
x,y = R .* cos.( theta ) .+ sx, R .* sin.( theta ) .+ sy;
剩下的就是显示这两个图形,以便进行直观比较。
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 )
很明显,模型非常吻合。
结论¶
我们使用 Engee 基本模块建立了一个近似黄金螺旋的数学模型。然后,我们使用软件控制指令将几个信号可视化,并将结果与黄金螺旋方程进行比较。
参考资料
[1] Duan J. S. 黄金矩形、斐波纳契螺旋和黄金螺旋的收缩点 //Discrete Dynamics in Nature and Society.- 2019.- Т. 2019.- С. 1-6.