簡體   English   中英

在L系統森林中重疊的樹木

[英]Overlapping trees in L-system forest

我使用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()

我認為問題更多的是樹木本身的特征的規律性,而不是它們本身的位置。

一種可能的解決方案是添加突變。 對於“發育遲緩”的全球控制,您可以抑制5%的生產應用程序。 這樣可以使松散的樹更加松散地跟隨模型。

為了更好地控制,您可以使用不同的重量來抑制每個生產。

查看The Algorithmic Beauty of Plants部分1.7隨機L系統了解更多信息。 他們使用概率在單個規則的幾個變體中進行選擇。

根據我對L系統的理解,有一個完整的語法不是隨機選擇的。 你能提供一些關於你的語法如何工作的細節嗎? 我想你可以通過制作一個從起始角度超過90度的有限的,封閉式的制作組合來限制樹木成長的方向。

但是你不能完全隨機化起始角度...你可能需要在一定范圍內隨機化它? 當然,如果你的L系統只是隨機產生一切,它就會像一堆噪音。 有一個目的是限制你的初始條件; 每個語法都有一個開始符號,你需要利用你的開始符號來生成有意義的東西。 我想你希望你的開始符號總是指向上方。

但是我很久沒有研究L系統了,所以我的答案就是一點點。

編輯:

這是一個有趣的限制,因為它聽起來像樹木自然而然地做的事情。 在自然界中我認為這是因為只有一定量的陽光可以通過一定的地面,所以如果一棵樹已經在某個地方生長,那么其他任何東西都無法生長。

作為一個AI人,我喜歡將現實世界的解決方案變成有趣的啟發式方法。 我們在這里尋找什么樣的啟發式? 那么,二維坐標系中的“地面補丁”只是一系列x坐標。 如果在不斷增長的葉子的任意x范圍內有太多的東西,也許會有一些東西讓增長失去動力? (不是python xrange,而是一系列x坐標,如果你願意,還會有一些“delta”值。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM