【问题标题】:How do I create a spiral off-shoot from my larger spiral?如何从较大的螺旋中创建螺旋分支?
【发布时间】:2016-03-14 20:30:20
【问题描述】:

我正在用 python 编码。我用下面的当前 for 循环创建了一个螺旋。我想每 10 度左右创建一个微小的螺旋分支。问题是我不知道该怎么做。我正在尝试做这样的事情:

我的问题是如何创建分支?这甚至可能吗? 非常感谢任何建议。

import turtle
import math
me = turtle.Turtle()


def miniSpiral():
    for i in range(0,360):
        x,y = me.position()
        me.left(1)
        if x%10==0:
            x2,y2 = me.forward(((5*i)+5)*math.pi/360)
        else:
            x2,y2= me.forward(5*math.pi/360)
        me.goto((x+x2),(y+y2))

for x2 in range(0,720):
    me.left(1)
    if x2%10==0:
        me.forward(((10*x2)+10)*math.pi/360)
        #miniSpiral()
    me.forward(10*math.pi/360)

【问题讨论】:

  • 我对你的代码感到困惑。当我在 Python 2.7 或 3.5 上使用 turtle 库时,我没有从 Turtle 对象上的 forward 方法获得任何返回值。您还向它传递了一个看起来像是一个角度而不是距离的值。您使用的是非标准的turtle 模块吗?
  • 我实际上想到,当您沿着圆弧或圆的圆周测量时,在一定距离内使用pi 可能是合适的,因此我的部分评论可能无效。

标签: python fractals


【解决方案1】:

一般来说,以编程方式绘制分形的最简单方法是使用递归。从代码开始绘制分形的一个“段”。在您链接到的图像中,那将是螺旋的一个 90 度角(因为这是分支之间的距离)。

一旦您的代码可以绘制一个段,您就可以对其添加递归调用。给它一些参数(例如初始大小),并让递归调用减少传递给下一次调用的值。添加一个基本情况,即跳过该参数集太小的调用(例如if size < 1: return),这样递归就不会永远持续下去。

现在您可以添加分支。不要只进行一次递归调用,而是进行两次。您需要添加一些额外的逻辑来在调用之间移动海龟的位置(因此第二个从与第一个大致相同的位置开始),但这不应该太难。为了使两个分支不同,改变它们的初始位置或角度,或者给它们不同的参数。在您的示例图像中,“额外”分支都从“主”分支开始向相反方向发展,并且它们开始变小。

这是您想要的螺旋的伪代码实现(我没有添加实际的 turtle 代码,因为您似乎使用的 turtle 模块与标准库中的模块不同):

def spiral(size):
    if size < 1: return # base case
    draw_segment(size) # this draws a 90 degree piece of the spiral

    position = getposition() # save state so we can back up after the first recursive call
    angle = getangle()

    spiral(size - 1) # main branch of the recursion

    penup()  # restore state (mostly)
    setposition(position)
    pendown()
    setangle(angle + 180) # we want to start facing the other direction for the second branch

    spiral(size - 2) # extra branch of the recursion

您可以调整细节(例如如何修改 size 以进行递归调用)以满足您的口味或您正在寻找的分形设计。例如,您可以将大小乘以某个因子(例如 size * 0.75),而不是减去一个固定的数量。

【讨论】:

    【解决方案2】:

    每个迷你螺旋只是原始螺旋的一个较小版本,因此您可以小心地调用原始函数来制作每个较小的螺旋。

    import turtle
    import math
    
    
    def spiral(steps, left, forward, level):
        for step in range(50, steps):
            me.left(left)
            me.forward(step / forward)
    
            if step % 200 == 0 and level > 0:
                x, y = me.position()
                heading = me.heading()
                spiral((steps * 2) / 3, -left * 1.2, forward * 1.2, level - 1)
                me.up()
                me.setpos(x, y)
                me.setheading(heading)
                me.down()
    
    #turtle.tracer(5, 200)     # to speed things up
    me = turtle.Turtle()
    spiral(800, 0.6, 200.0, 4)
    

    每次调用spiral(),参数都会稍微修改,级别会降低1。此外,left 参数设为负数,这具有改变每个子螺旋方向的效果。在200 步骤之后调用每个子螺旋。每个子螺旋都有原始步骤的 2/3,依此类推....有很多数字可以玩,看看它们如何影响结果。当子螺旋完成绘制时,它会跳回开始绘制它的点,并继续原来的螺旋。

    例如,以0 的级别调用它会给你一个简单的螺旋。

    这将为您提供以下类型的输出:

    【讨论】:

      猜你喜欢
      • 2022-10-15
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多