簡體   English   中英

使用 python 實現參數化 L 系統

[英]Implementing a parametric L-system using python

我一直在研究用 python 實現參數化 L 系統。 我的案例是一棵 2D 樹,因此我使用的是 python 海龜庫。 我為一個非參數 L 系統編寫了這個簡單的代碼,它工作得很好。 這是我的代碼:

import turtle as T


class LSystem:
    def __init__(self, axiom, width, length, angle):
        self.axiom = axiom
        self.state = axiom
        self.width = width
        self.length = length
        self.angle = angle
        self.rules = {}
        T.pensize(self.width)

    def add_rules(self, *rules):
        for arg in rules:
            self.rules[arg[0]] = arg[-1]

    def single_generation(self):
        next_state = ""
        for char in self.state:
            if char in self.rules:
                next_state += self.rules[char]
            else:
                next_state += char
        self.state = next_state

    def set_turtle(self, my_tuple):
        T.up()
        T.goto(my_tuple[0], my_tuple[1])
        T.seth(my_tuple[2])
        T.down()

    def length_function(self, r):
        self.length *= r

    def width_function(self, q, e):
        self.width *= q**e

    def draw_turtle(self):
        turtle_state = []
        # ***************
        T.tracer(0, 0)
        T.down()
        T.ht()
        T.speed(0)
        T.seth(90)
        # ***************
        for move in self.state:
            if move == "[":
                turtle_state.append((T.xcor(), T.ycor(), T.heading(), T.pensize()))
            elif move == "]":
                xcor, ycor, head, wid = turtle_state.pop()
                self.set_turtle((xcor, ycor, head))
                self.width = wid
            elif move == 'F':
                T.fd(self.length)
                T.pensize(self.width)
            elif move == '+':
                T.left(self.angle)
            elif move == '-':
                T.right(self.angle)
        T.getscreen()
        T.done()


if __name__ == '__main__':
    my_axiom = "A"
    my_width = 10
    my_length = 60
    my_angle = 33.5
    LSys = LSystem(my_axiom, my_width, my_length, my_angle)
    my_rule = ("A", "F[+A][-A]")
    LSys.add_rules(my_rule)
    LSys.single_generation()
    LSys.single_generation()
    LSys.single_generation()
    LSys.single_generation()
    LSys.single_generation()
    LSys.draw_turtle()

問題是這段代碼適用於一個簡單的非參數 L 系統,但我想在每一步中減少我的樹的直徑和長度。 我為此編寫了兩個函數, length_functionwidth_function但我不知道在哪里或如何使用它。 這是我的 L 系統規則和公理:

A(s,w) ------> F(s,w)[+A(s*r1, w* q^e)][-A(s*r2, w* (1-q)^e]
axiom = "A(s0, w0)"

r1, r2, q, e是已知的。 s0 & w0也是已知的。 我不想以字符串格式存儲這些參數的值,我想將它們存儲在列表或數組中,但我不知道如何。 這是我嘗試繪制的樹的圖片與我的代碼繪制的內容: 參數樹 在此處輸入圖片說明

當您遇到 '[' 時,您可以正確存儲 pensize,但沒有減少它。

做類似的事情:

if move == "[":
  self.width *= 0.95
  turtle_state.append((T.xcor(), T.ycor(), T.heading(), self.width))

暫無
暫無

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

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