【问题标题】:Implementing the Koch Curve?实施科赫曲线?
【发布时间】:2009-05-31 15:24:10
【问题描述】:

我正在查看 Koch Snowflake (here) 的 wikipedia 页面,并且对所有示例都采用徽标/海龟样式感到困扰。所以我开始制作我自己的返回列表或坐标的。

我的实现是在 python 中,我基本上撕掉了 python turtle 的实现,但是用基本的 trig 替换了海龟特定的东西。它导致了一些丑陋的代码。我对你的挑战是要么改进我的代码,要么自己想出一个更优雅的解决方案。它可以是 python,也可以是你喜欢的语言。

我的代码:

from math import sin, cos, radians

def grow(steps, length = 200, startPos = (0,0)):
    angle = 0
    try:
        jump = float(length) / (3 ** steps)
    except:
        jump = length

    set="F"
    for i in xrange(steps): set=set.replace("F", "FLFRFLF")

    coords = [startPos]
    for move in set:
        if move is "F": 
            coords.append(
              (coords[-1][0] + jump * cos(angle),
               coords[-1][1] + jump * sin(angle)))
        if move is "L":
            angle += radians(60)
        if move is "R":
            angle -= radians(120)

    return coords

编辑:由于懒惰复制,我忘记了导入

【问题讨论】:

  • "set" 是 Python 中的内置类型
  • 实际上,当我想到更好的实现时,我最终会重写一个类似 Turtle 的类。也没有必要每次都计算 jump * cos(angle) & jump * sin(angle),知道只有 6 个可能的角度......

标签: python fractals


【解决方案1】:

我不认为它特别难看,我只会逐步重构它,例如作为第一步(我已经删除了try/except,因为我不知道你要防止什么......如果它需要重新进入它应该更明确一点,恕我直言):

import math

angles = [math.radians(60*x) for x in range(6)]
sines = [math.sin(x) for x in angles]
cosin = [math.cos(x) for x in angles]

def L(angle, coords, jump):
    return (angle + 1) % 6
def R(angle, coords, jump):
    return (angle + 4) % 6
def F(angle, coords, jump):
    coords.append(
        (coords[-1][0] + jump * cosin[angle],
         coords[-1][1] + jump * sines[angle]))
    return angle

decode = dict(L=L, R=R, F=F)

def grow(steps, length=200, startPos=(0,0)):
    pathcodes="F"
    for i in xrange(steps):
        pathcodes = pathcodes.replace("F", "FLFRFLF")

    jump = float(length) / (3 ** steps)
    coords = [startPos]
    angle = 0

    for move in pathcodes:
        angle = decode[move](angle, coords, jump)

    return coords

如果有必要进行第二步,我可能会将这个功能整合到一个类中,但我不确定这会使事情变得更好(或者,实际上更好;-)。

【讨论】:

  • 感谢您的解决方案。尝试/除了我是愚蠢的,忘记把它拿出来。最初是为了捕捉零除错误。
  • 我注意到这个有很好的速度提升!学习的好剧本!
【解决方案2】:

我非常喜欢你的问题,所以我将它的答案作为一个新问题发布,以便其他人可以改进它:

https://stackoverflow.com/questions/7420248

我没有使用 Logo/Turtle 的东西,也没有使用三角函数。

恭喜您成为第一个将这个问题带到 StackOverflow 的人!

【讨论】:

    【解决方案3】:

    Mathematica 在数学方面更胜一筹:

    points = {{0.0, 1.0}};
    koch[pts_] := Join[
        pts/3,
        (RotationMatrix[60 Degree].#/3 + {1/3, 0}) & /@ pts,
        (RotationMatrix[-60 Degree].#/3 + {1/2, 1/Sqrt[12]}) & /@ pts,
        (#/3 + {2/3, 0}) & /@ pts
    ];
    Graphics[Line[Nest[koch, points, 5]], PlotRange -> {{0, 1}, {0, 0.3}}] //Print
    

    【讨论】:

      【解决方案4】:

      需要考虑的一点是,如果不是为了您的实现,那么为了测试您的实现,Python 乌龟可以记录它正在做的事情并将坐标返回给您。您在要记录的代码周围使用begin_poly()end_poly(),然后使用get_poly() 获得积分。

      在此示例中,我将根据 code from this site 绘制雪花,然后将这些坐标注册为新的海龟形状,我将在屏幕上随机(快速)标记:

      import turtle
      from random import random, randrange
      
      def koch_curve(turtle, steps, length):
          if steps == 0:
              turtle.forward(length)
          else:
              for angle in [60, -120, 60, 0]:
                  koch_curve(turtle, steps - 1, length / 3)
                  turtle.left(angle)
      
      def koch_snowflake(turtle, steps, length):
          turtle.begin_poly()
      
          for _ in range(3):
              koch_curve(turtle, steps, length)
              turtle.right(120)
      
          turtle.end_poly()
      
          return turtle.get_poly()
      
      turtle.speed("fastest")
      
      turtle.register_shape("snowflake", koch_snowflake(turtle.getturtle(), 3, 100))
      
      turtle.reset()
      
      turtle.penup()
      
      turtle.shape("snowflake")
      
      width, height = turtle.window_width() / 2, turtle.window_height() / 2
      
      for _ in range(24):
          turtle.color((random(), random(), random()), (random(), random(), random()))
          turtle.goto(randrange(-width, width), randrange(-height, height))
          turtle.stamp()
      
      turtle.done()
      

      如果您不希望用户看到此步骤,可以在多边形生成期间隐藏笔和海龟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-03
        相关资源
        最近更新 更多