斐波那契葵Tkinter

3
我正在尝试使用tkinter绘制一个斐波那契向日葵。它可以正确绘制出来,但我想要能够绘制出旋转曲线。然而,我无法弄清如何正确地将它们连接起来。有什么想法吗?
以下是我的代码:
import math
from tkinter import *

def s5(n,r): #works better for first direction
    spirals = []
    for i in range(n+1):
        spirals.append(((r*(i**0.5),((i*(360)/(((5**0.5)+1)/2))%360))))
    return spirals

# convert to cartesian to plot
def pol2cart(r,theta):
    x = r * math.cos(math.radians(theta))
    y = r * math.sin(math.radians(theta))
    return x,y

# set size of fib sun
num_points = 200
distance = 15

# do the cartesian conversion
coordinates = [pol2cart(r,t) for r,t in s5(num_points,distance)]

# center for the canvas
coordinates = [(x+250,y+250) for x,y in coordinates]

# create gui
master = Tk()
canvas = Canvas(master,width = 500,height=500)
canvas.pack()



# plot points 
h= 1
for x,y in coordinates:
    canvas.create_oval(x+7,y+7,x-7,y-7)
    canvas.create_text(x,y,text=h)
    h += 1

mainloop()

这是我想要实现的结果: 目标

1
你知道Canvas有用于绘制线条和弧线的命令吗? - Bryan Oakley
是的...我只是不确定如何创建正确的螺旋形。 - Kmat
终于用tkinter创建了一些有趣的东西! - nbro
2个回答

4
这是一个有趣的问题,我刚刚草拟了一个可能的解决方案。您可以从1到20开始,首先将每个数字加上21。也就是说,您应该连接1到22,22到43,43到64,...然后再连接2到23,23到44,...这样做会给您一个螺旋的方向。
对于另一个方向,您可以做同样的事情,但是从1到34开始,并将34加到每个数字。也就是说,您从1开始,加上34。1、35、69、... 2、36、70、...
这两个图显示了这些螺旋形状:enter image description hereenter image description here 实际上,这些数字并不神奇,它们来自于斐波那契数列,并且基于螺旋的层数,您应该能够检测到它。因此,您总是有像0、1、1、2、3、5、8、13、21、34、55这样的数字差异。

嗯,这个方案很完美,但我正在尝试寻找一种动态的方法。图像中节点的数量可能会发生变化,这对于每种情况都不成立。 - Kmat
事实上,这些数字并非神奇,而是来自于斐波那契数列,并且基于你的螺旋图层,你应该能够检测到它。因此,您始终会有像下面这样的数字差异:0、1、1、2、3、5、8、13、21、34、55…… - Good Luck
确切地说,我只是在寻找正确的方程式来正确检测螺旋中下一个节点应该是哪个。 - Kmat
根据您的花瓣层数,选择两个连续的斐波那契数(比如21和34),然后将您的数字x连接到x+21和x+34。 - Good Luck

2
下面这个版本的程序能够画出线条,但是我还没有找到为什么步长要设置成21和34的原因。我怀疑这与您在s5函数中使用的数字('5')有关。
import math
from Tkinter import *

class Fibonacci():
    def s5(self, n, r): # works better for first direction
        spirals = []
        for i in range(n+1):
            spirals.append(((r*(i**0.5),((i*(360)/(((5**0.5)+1)/2))%360))))
        return spirals

    def pol2cart(self, r, theta):
        x = r * math.cos(math.radians(theta))
        y = r * math.sin(math.radians(theta))
        return x,y

    def calculate_coordinates(self, num_points = 200, distance = 15):
        # do the cartesian conversion
        self.coordinates = [self.pol2cart(r, t) for r, t in self.s5(num_points, distance)]

        # center for the canvas
        self.coordinates = [(x+250,y+250) for x, y in self.coordinates]

    def plot_numbers(self, canvas):
        h = 1
        self.calculate_coordinates(num_points = 200, distance = 15)
        for x, y in self.coordinates:
            canvas.create_oval(x+7, y+7, x-7, y-7)
            canvas.create_text(x, y, text = h)
            h += 1

    def plot_lines(self, canvas):
        for delta in [21, 34]:
            for start in range(34):
                x0, y0 = self.coordinates[0]
                i = start
                while i < len(self.coordinates):
                    x1, y1 = self.coordinates[i]
                    canvas.create_line(x0, y0, x1, y1)
                    x0 = x1; y0 = y1
                    i += delta

    def create_gui(self):
        master = Tk()
        canvas = Canvas(master, width = 500, height = 500)
        canvas.pack()

        self.plot_numbers(canvas)
        self.plot_lines(canvas)

        mainloop()

def main():
    f = Fibonacci()
    f.create_gui()
    return 0

if __name__ == '__main__':
    main()

为了消除中心点作为起点,需要像这样修改plot_lines:

enter image description here

def plot_lines(self, canvas):
    for delta in [21, 34]:
        for start in range(34):
            x0, y0 = self.coordinates[start]
            print x0, y0
            i = start + delta
            while i < len(self.coordinates):
                x1, y1 = self.coordinates[i]
                canvas.create_line(x0, y0, x1, y1)
                x0 = x1; y0 = y1
                i += delta

这将得到:输入图片描述

这些数字来自于斐波那契数列...你也可以使用13和21得到花纹...较小的数字意味着更圆形的螺旋,节点数量更多,而较大的数字则产生较小的螺旋,节点数量较少。 - Good Luck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接