3

私はコッホスノーフレークのウィキペディアページ(ここ)を見ていましたが、すべての例がロゴ/タートルスタイルであることに悩まされていました。だから私はリストや座標を返す自分のものを作ることに着手しました。

私の実装はPythonであり、基本的にpython turtleの実装を取り除いたが、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

編集:怠惰なコピーのために、私はインポートを忘れました

4

4 に答える 4

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

2番目のステップが必要な場合は、おそらくこの機能をクラスにロールアップしますが、それによって状況が大幅に改善されるかどうかはわかりません(または、実際にはまったく改善されます;-)。

于 2009-05-31T17:25:20.963 に答える
2

あなたの質問がとても気に入ったので、他の人が改善できるように、新しい質問として回答を投稿しました。

https://stackoverflow.com/questions/7420248

Logo/Turtle も、三角法も使用しませんでした。

この問題を StackOverflow にもたらした最初の人物であることを祝福します!

于 2011-09-14T17:13:00.840 に答える
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
于 2009-10-09T08:07:10.973 に答える
0

実装ではなく、実装をテストするために考慮すべきことは、Python タートルが何をしているかを記録し、座標を返すことができるということです。記録したいコードの周りを使用し、後でbegin_poly()使用してポイントを取得します。end_poly()get_poly()

この例では、このサイトのコードに基づいて雪の結晶を描画し、それらの座標を新しいタートル シェイプとして登録し直して、画面上でランダムに (そしてすばやく) スタンプします。

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()

このステップをユーザーに見せたくない場合は、ポリゴン生成中にペンを上げてタートルを非表示にすることができます。

ここに画像の説明を入力

于 2017-01-01T02:59:16.770 に答える