如何实现科赫曲线?

3 投票
4 回答
5692 浏览
提问于 2025-04-15 11:57

我在看维基百科上的科赫雪花(这里)页面时,发现所有的例子都是用logo或海龟绘图风格的,这让我有点烦。所以我决定自己做一个,返回一组坐标。

我的实现是用Python写的,基本上是抄袭了Python海龟绘图的实现,不过把海龟特有的部分换成了基本的三角函数。这导致我的代码看起来有点乱。现在我给你们的挑战是,改进我的代码,或者想出一个更优雅的解决方案,可以用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

编辑:因为复制得太随便,我忘了导入相关库。

4 个回答

0

在数学方面,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
2

我非常喜欢你的问题,所以我把它作为一个新问题发了个回答,这样其他人也可以帮忙改进它:

https://stackoverflow.com/questions/7420248

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

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

7

我觉得这段代码并没有特别难看,我会选择逐步改进,比如作为第一步(我把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

如果有必要进行第二步的话,我可能会把这个功能放进一个类里,但我不确定这样做是否真的能让事情变得更好(或者说根本没有改善;-)。

撰写回答