2017-07-26 170 views
1

我想在python中创建一个分形树。我已经制作了树,但我想要有2只或更多的海龟来一次绘制我的分形树。有没有办法做到这一点?我寻找解决方案,但没有一个是我真正想要的。这里是我的代码:如何在Python3中一次移动2个海龟

import turtle 
tree = turtle.Turtle() 
tree.ht() 
tree.penup() 
tree.sety(-200) 
tree.left(90) 

import turtle 
tree0 = turtle.Turtle() 
tree0.ht() 
tree0.penup() 
tree0.sety(-200) 
tree0.left(90) 

startx = tree.xcor() 
starty = tree.ycor() 
startx = tree0.xcor() 
starty = tree0.ycor() 

def fractalright(angle, length, x, y): 
    tree.speed(0) 
    tree.setx(x) 
    tree.sety(y) 
    tree.pendown() 
    tree.forward(length) 
    tree.right(angle) 
    length = length - 20 
    x = tree.xcor() 
    y = tree.ycor() 
    if length < 0: 
     return 
    tree.penup() 
    fractalright(angle, length, x, y) 
    tree.penup() 
    tree.setx(x) 
    tree.sety(y) 
    tree.left(angle) 
    fractalright (-angle, length, x, y) 
def fractalleft(angle, length, x, y): 
    tree0.speed(0) 
    tree0.setx(x) 
    tree0.sety(y) 
    tree0.pendown() 
    tree0.forward(length) 
    tree0.right(angle) 
    length = length - 20 
    x = tree0.xcor() 
    y = tree0.ycor() 
    if length < 0: 
     return 
    tree0.penup() 
    fractalleft(angle, length, x, y) 
    tree0.penup() 
    tree0.setx(x) 
    tree0.sety(y) 
    tree0.left(angle) 
    fractalleft (-angle, length, x, y) 

我使用python 3,请让我知道如果你知道一个解决方案。谢谢!!

+0

你提到了[multiprocessing](https://docs.python.org/2/library/multiprocessing.html),你看过那个文档,另一个选项是[threading](https:/ /docs.python.org/2/library/threading.html),我会建议看看他们,然后尝试一个,然后如果你仍然有问题回来这些。 –

回答

0

使用模块threadingturtle的关键是不能让额外的线程来操纵海龟 - 他们,而不是排队的龟请求,并让他们的主线程处理:我们正在使用

import queue 
from threading import Thread, active_count 
from turtle import Turtle, Screen 

def forward(turtle, distance): 
    graphics.put((turtle.forward, distance)) 

def right(turtle, angle): 
    graphics.put((turtle.right, angle)) 

def left(turtle, angle): 
    graphics.put((turtle.left, angle)) 

def fractalright(turtle, angle, length): 
    forward(turtle, length) 

    if length - 20 > 0: 
     right(turtle, angle) 
     fractalright(turtle, angle, length - 20) 
     left(turtle, angle) 
     fractalright(turtle, -angle, length - 20) 

    forward(turtle, -length) 

def fractalleft(turtle, angle, length): 
    forward(turtle, length) 

    if length - 20 > 0: 
     left(turtle, angle) 
     fractalleft(turtle, angle, length - 20) 
     right(turtle, angle) 
     fractalleft(turtle, -angle, length - 20) 

    forward(turtle, -length) 

def process_queue(): 
    while not graphics.empty(): 
     action, argument = graphics.get() 
     action(argument) 

    if active_count() > 1: 
     screen.ontimer(process_queue, 100) 

START_X, START_Y = 0, -200 

screen = Screen() 
screen.mode('logo') # make starting direction 0 degrees towards top 

tree1 = Turtle(visible=False) 
tree1.color('green') 
tree1.penup() 
tree1.goto(START_X, START_Y) 
tree1.pendown() 

tree2 = Turtle(visible=False) 
tree2.color('dark green') 
tree2.penup() 
tree2.goto(START_X, START_Y) 
tree2.pendown() 

graphics = queue.Queue(1) # size = number of hardware threads you have - 1 

def fractal1(): 
    fractalright(tree1, 30, 100) 

def fractal2(): 
    fractalleft(tree2, 30, 100) 

thread1 = Thread(target=fractal1) 
thread1.daemon = True # thread dies when main thread (only non-daemon thread) exits. 
thread1.start() 

thread2 = Thread(target=fractal2) 
thread2.daemon = True # thread dies when main thread (only non-daemon thread) exits. 
thread2.start() 

process_queue() 

screen.exitonclick() 

用于线程安全通信的队列模块。我重写了您的fractalright()fractalleft()函数,以尽量减少它们所需的各种图形操作。

enter image description here

如果一切正常,你应该看到在同一时间独立地绘制树的浅绿色和深绿色的部分。您的计算机需要至少有几个硬件线程可用。

1

蒸馏掉你如何绘制树的细节,基本的任务是执行一些绘制函数的两个实例并行使用不同的参数来指定一个“左树”和一个“右树”。这种基本结构可实现如下:

from multiprocessing.dummy import Pool 
import time 


def draw_function(current_tree): 
    # Replace the following lines with what you need to do with turtles 
    print("Drawing tree {}".format(current_tree)) 
    time.sleep(1) 


# Replace this with list of tuples of arguments to draw_function specifying 
# angle, length, x, y, left vs right, etc. 
list_of_trees = ["left_tree", "right_tree"] 

my_pool = Pool(2) 

results = my_pool.map(draw_function, list_of_trees) 

my_pool.close() 
my_pool.join() 

在你的情况,我对fractalleftfractalright之间的区别有点不清楚,因为他们似乎是相同的,但逻辑应该成为你的draw_function的基础。您应该为draw_function的每次执行创建一个单独的乌龟,但请注意,您不需要重新导入乌龟。

+0

我有一个问题,你是什么意思将它替换为draw_function指定角度,长度,x,y,左,右等参数的元组列表。 –

+0

假设您的draw_function结果需要参数angle,length,x ,y和一个布尔值,指定它是“左”型树还是“右”型树。如果你有两棵树可以绘制,你可以创建一个由两个元组组成的列表,每个元组包含其中一棵树的适当参数。然后,draw_function将接受并分析该元组以确定如何绘制树。可能更好的做法是让draw_function接受一个自定义Tree类实例的单个参数,该实例指定绘制树所需的所有内容。 – wphicks