【问题标题】:Rephrase spirograph code into function将spirograph代码改写为函数
【发布时间】:2015-07-20 10:33:29
【问题描述】:

我正在编写一个 python spirograph 程序,我需要一些帮助来将它的一部分转换为一个函数。该代码试图重现我在here 找到的视频中说明的结果。一条线绕原点旋转,然后另一条线绕原点旋转,依此类推。

通过对(我认为是)三角学的一点研究,我组合了一个函数rotate(point, angle, center=(0, 0))。用户输入要旋转的点、要旋转的角度(顺时针)以及要旋转的中心点。

然后,我实施了一个初始测试,其中一条线围绕另一条线旋转。第二行的结尾就像拿着一支笔一样。代码有点乱,但看起来是这样的。

x, y = 0, 0
lines = []

while 1:

    point1 = rotate((0,50), x)
    point2 = map(sum,zip(rotate((0, 50), y), point1))
    if x == 0:
        oldpoint2 = point2
    else:
        canvas.create_line(oldpoint2[0], oldpoint2[1], point2[0], point2[1])
    lines.append( canvas.create_line(0, 0, point1[0], point1[1]) )
    lines.append( canvas.create_line(point1[0], point1[1], point2[0], point2[1]) )
    oldpoint2 = point2

    tk.update()

    x += 5
    if x > 360 and y > 360:
        x -= 360
        canvas.delete("all")
        time.sleep(1)
    y += 8.8
    if y > 360: y -= 360

    for line in lines:
        canvas.delete(line)
    lines = []

太好了,完美运行。然而,我的最终目标是视频中的内容。在视频中,用户可以输入任意数量的手臂,然后定义每个手臂的长度和角速度。我的只能用两条手臂工作。归根结底,我的问题是如何将我发布的代码放入一个看起来像drawSpiral(arms, lenlist, velocitylist) 的函数中。它将以臂的数量、每个臂的速度列表和每个臂的长度列表作为参数。

我的尝试

我已经尝试过几次了。最初,我有一些根本不起作用的东西。我得到了一些很酷的形状,但绝对不是想要的输出。我已经工作了几个小时,我能得到的最接近的是:

def drawSpiral(arms, lenlist, velocitylist):
    if not arms == len(lenlist) == len(velocitylist):
        raise ValueError("The lists don't match the provided number of arms")

    iteration = 0
    while 1:

        tk.update()

        iteration += 1

        #Empty the list of points
        pointlist = []
        pointlist.append((0, 0))

        #Create a list of the final rotation degrees for each point
        rotations = []
        for vel in velocitylist:
            rotations.append(vel*iteration)


        for n in range(arms):
            point = tuple(map(sum,zip(rotate((0, lenlist[n]), rotations[n], pointlist[n]))))
            pointlist.append(point)

        for point in pointlist:
            create_point(point)
        for n in range(arms):
            print pointlist[n], pointlist[n+1]

我觉得这与我的解决方案相当接近,但并不完全如此。调用drawSpiral(2, [50, 75], [1, 5]) 看起来可能会产生一些正确的点,但没有连接正确的集合。盯着它看了大约一个小时,尝试了一些东西,我没有任何进展。看着自己的代码,我也很困惑。我被困住了!围绕中心旋转的点连接到一个在屏幕上对角线并返回的点。连接到中心的线来回伸展。有人能指出我正确的方向吗?

进一步测试的结果

我已经设置了两个函数来在每条手臂的末端绘制点,并发现了一些有趣的结果。在这两种情况下,第一个手臂以 5 的速度旋转,第二个手臂以 -3 的速度旋转。函数外部的循环正在生成模式:

drawSpiral(2, [50, 50], [5, -3]) 调用的函数产生 的结果

它似乎在拉伸上半部分。当双臂的速度为 5 时,预计该函数会产生两个圆,一个比另一个大。但是,它会产生一个倒置的心形,点连接到中心。

现在有更多证据了,有谁比我懂数学的能帮帮我吗?

【问题讨论】:

  • 我没有看到 rotate 的定义。我要检查的一件事是度数与弧度。
  • Rotate 运行良好,初始代码运行良好。
  • @PatriciaShanahan 我添加了一些图片。

标签: python function python-2.7 tkinter rotation


【解决方案1】:

你的错误在

 for n in range(arms):
        point = tuple(map(sum,zip(rotate((0, lenlist[n]), rotations[n], pointlist[n]))))
        pointlist.append(point)

具体来说,

rotate((0, lenlist[n])

替换为

 for n in range(arms):
        point = tuple(map(sum,zip(rotate((pointlist[n][0], lenlist[n]), rotations[n], pointlist[n]))))
        pointlist.append(point)

您违反了极坐标(圆形图)的常用数学符号,这导致了您的困惑和最终的问题。据我所知,您的函数正在绘制一个 (X,Y) 点 (0,length),然后找到该点与中心点之间的差异(正确定义为您找到的最后一个点)并将其旋转那个中心。问题是 (0,length) 不是 'length' 远离中心。通过将 (0,lenlist[n]) 替换为 (pointlist[n][0],lenlist[n]) 可以根据最后一个点生成下一个点。

我还建议将您的旋转函数编辑为旋转(长度,角度,中心点),这将简化输入为更传统的表示形式。

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多