4

森の中の木の成長をシミュレートするPythonのタートルグラフィックスを使用してプログラムを作成しました。ランダムに選択される3つのツリーパターンがあり、それらの開始座標と角度もランダムに選択されます。かっこいい木の模様をいくつか選びましたが、問題はたくさんの木が重なっていることです。そのため、木の森のように見えるのではなく、5歳の悪い絵のように見えます。

この重複を少なくする方法はありますか?森を見ると、いくつかの木とその葉が重なっていますが、それは間違いなく次のようには見えません。

ここに画像の説明を入力してください

ランダム化がたくさんあるので、どう対処したらいいのかわかりませんでした。

これが私のコードです:

import turtle
import random

stack = []

#max_it = maximum iterations, word = starting axiom such as 'F', proc_rules are the rules that 
#change the elements of word if it's key is found in dictionary notation, x and y are the 
#coordinates, and turn is the starting angle 

def createWord(max_it, word, proc_rules, x, y, turn):

    turtle.up()
    turtle.home()
    turtle.goto(x, y)
    turtle.right(turn)
    turtle.down()

    t = 0
    while t < max_it:
        word = rewrite(word, proc_rules)
        drawit(word, 5, 20)
        t = t+1


def rewrite(word, proc_rules):

   #rewrite changes the word at each iteration depending on proc_rules

    wordList = list(word)

    for i in range(len(wordList)):
        curChar = wordList[i]
        if curChar in proc_rules:
            wordList[i] = proc_rules[curChar]

    return "".join(wordList)


def drawit(newWord, d, angle):

    #drawit 'draws' the words

    newWordLs = list(newWord)
    for i in range(len(newWordLs)):
        cur_Char = newWordLs[i]
        if cur_Char == 'F':
            turtle.forward(d)
        elif cur_Char == '+':
            turtle.right(angle)
        elif cur_Char == '-':
            turtle.left(angle)
        elif cur_Char == '[':
            state_push()
        elif cur_Char == ']':
            state_pop()


def state_push():

    global stack

    stack.append((turtle.position(), turtle.heading()))


def state_pop():

    global stack

    position, heading = stack.pop()

    turtle.up()
    turtle.goto(position)
    turtle.setheading(heading)
    turtle.down()


def randomStart():

    #x can be anywhere from -300 to 300, all across the canvas
    x = random.randint(-300, 300)

    #these are trees, so we need to constrain the 'root' of each
    # to a fairly narrow range from -320 to -280
    y = random.randint(-320, -280)

    #heading (the angle of the 'stalk') will be constrained 
    #from -80 to -100 (10 degrees either side of straight up)
    heading = random.randint(-100, -80)

    return ((x, y), heading)


def main():

    #define the list for rule sets.
    #each set is iteration range [i_range], the axiom and the rule for making a tree.  
    #the randomizer will select one of these for building.

    rule_sets = []
    rule_sets.append(((3, 5), 'F', {'F':'F[+F][-F]F'}))
    rule_sets.append(((4, 6), 'B', {'B':'F[-B][+ B]', 'F':'FF'}))
    rule_sets.append(((2, 4), 'F', {'F':'FF+[+F-F-F]-[-F+F+F]'}))

    #define the number of trees to build
    tree_count = 50

    #speed up the turtle
    turtle.tracer(10, 0)

    #for each tree...
    for x in range(tree_count):

        #pick a random number between 0 and the length
        #of the rule set -1 - this results in selecting
        #a result randomly from the list of possible rules.

        rand_i = random.randint(0, len(rule_sets) - 1)
        selected_ruleset = rule_sets[rand_i]

        #unpack the tuple stored for this ruleset
        i_range, word, rule = selected_ruleset

        #pick a random number inside the given iteration_range to be the 
        #iteration length for this command list.
        low, high = i_range
        i = random.randint(low, high)

        #get a random starting location and heading for the tree
        start_position, start_heading = randomStart()

        #unpack the x & y coordinates from the position
        start_x, start_y = start_position

        #build the current tree
        createWord(i, word, rule, start_x, start_y, start_heading)

if __name__ == '__main__': main()
4

2 に答える 2

2

問題は、樹木の配置自体ではなく、樹木自体の特徴の規則性にあると思います。

考えられる解決策は、突然変異を追加することです。「発育阻害」をグローバルに制御するには、実稼働アプリケーションのたとえば5%を抑制することができます。これにより、モデルに従うスパースツリーがより緩くなります。

より細かく制御するために、異なるウェイトで各プロダクションを抑制することができます。

詳細については、「植物のアルゴリズムの美しさ」セクション1.7確率的Lシステムを確認してください。彼らは確率を使用して、単一のルールのいくつかのバリエーションから選択します。

于 2012-09-25T16:18:40.843 に答える
2

Lシステムについての私の理解から、ランダムに選択されていない文法全体があります。文法がどのように機能するかについて詳しく教えてください。開始角度から90度以上離れた場所に限定されたクローズドエンドの作品セットを作成することで、木が成長する方向をいくらか制限できると思います。

しかし、開始角度を完全にランダム化することはできません...おそらく、特定の範囲内でランダム化する必要がありますか?もちろん、すべてをランダムに生成するLシステムがある場合は、ノイズの束のように見えます。初期条件に制限を設ける目的があります。すべての文法には開始記号があり、意味のあるものを生成するには、開始記号を利用する必要があります。スタートシンボルを常に上に向けてほしいと思います。

しかし、私は長い間L-systemを研究していないので、一粒の塩で答えてください。

編集:

これは、木が自然に行うことのように聞こえるという点で、課す興味深い制限です。自然界では、特定の地面に一定量の日光しか届かないために起こると思います。したがって、木がすでにどこかで成長している場合、他には何もできません。

AIの人である私は、現実世界のソリューションを興味深いヒューリスティックに変えるのが大好きです。ここでどのようなヒューリスティックを探していますか?2次元座標系の「地面のパッチ」は、x座標の範囲にすぎません。成長している葉の任意のx範囲内に物が多すぎると、成長の推進力を失うようなものがあるのではないでしょうか。(Pythonのxrangeではなく、x座標の範囲、必要に応じて「デルタ」値)。

于 2011-09-30T22:42:50.190 に答える