Python乌龟图形屡屡“出界”

时间:2018-09-24 15:28:53

标签: python python-3.x recursion turtle-graphics

我正在尝试让python中的 Turtle 随机绘制用户指定数量的三角形。在将乌龟保持在定义的范围内时,我遇到了一些麻烦。例如,乌龟的边界是

border = 300

def drawBorder(border):
    t.pensize(3)
    x = 0
    while x <= 4:
        t.pendown()
        t.forward(border)
        t.left(90)
        t.penup()
        x = x + 1

可绘制300x300的正方形。

  

以下功能应-当X或Y坐标+   将要绘制的三角形的长度在边界外-对于   前两次迭代尝试将乌龟旋转180度(面向   相反的方向)并将其向前移动两倍的距离   最初将其向前推进。如果这不能带来乌龟   在边界范围内,乌龟应返回到中间   的边界-在这种情况下,即(150,150)。这并不总是   发生。由于这一代人的“随机性”,大多数时候   乌龟最终落在边界外,尽管有时确实会吸引   边界内的所有三角形。

 if t.xcor() + lengthOfTriangle > border or t.xcor() + lengthOfTriangle < 0 or \
    t.ycor() + lengthOfTriangle > border or t.ycor() + lengthOfTriangle < 0:
x = 0
while x < 2:
    t.penup()
    t.left(180)
    t.forward(2 * lengthOfTriangle)
    t.pendown()
    x = x + 1
else:
    t.penup()
    if t.xcor() > border:
        t.seth(180)
    if t.xcor() < border:
        t.seth(0)
    t.forward(t.xcor() - (t.xcor() + border/2))
    if t.ycor() > border:
        t.seth(90)
    if t.ycor() < border:
        t.seth(270)
    t.forward(t.ycor() - (t.ycor() + border/2))

print("Turtle was going to be out of bounds. Xcor would be: ", t.xcor() + lengthOfTriangle,
      ". And Ycor would be: ", t.ycor() + lengthOfTriangle)
return drawFigureRec(numTriangles, lengthOfTriangle=random.randint(1, 20),
                     distanceTriangle=random.randint(1, 40),
                     angleTriangle=random.randint(0, 360), sum=sum)

如果您需要函数变量的上下文,例如,我已经链接了pastebin here

这是一张显示问题的图片。The turtle should stay within the 'bounds' (red square), but goes outside as shown by the console's output

1 个答案:

答案 0 :(得分:0)

您的代码有几个问题。例如,此边界检查逻辑完全忽略了乌龟的当前航向:

   if t.xcor() + lengthOfTriangle > border or ... t.ycor() + lengthOfTriangle > border or ...

即它始终假定为+45度,因此无法正常工作。你可以做 三角函数,或者简单地将乌龟移到新位置, 测试是否超出范围。如果超出范围,您可以将其移回, 调整并重试。 turtle.undo()方法在这里很有帮助。

您的drawFigure*()函数有时会显式返回值, 有时不是。一旦一个函数显式返回一个值,它应该 从所有退出点显式返回一个,而不隐式返回 有时None

您的方形边框有五个侧面:

   x = 0
   while x <= 4:

由于最后一个覆盖第一个,因此在视觉上不明显。

让我们尝试一种更简单的迭代方法,在该方法中,我们使用turtle.circle()绘制三角形,但是在确定每个三角形是否在边界内时将其视为一个圆。我们还将使图形居中,而不只是使用右上象限和正数:

from turtle import Screen, Turtle
from random import randint

NUMBER_TRIANGLES = 80
PEN_SIZE = 3
BORDER = 300

def drawBorder(border):
    turtle.pensize(PEN_SIZE)

    turtle.penup()
    turtle.goto(-border/2, -border/2)
    turtle.pendown()

    for _ in range(4):
        turtle.forward(border)
        turtle.left(90)

    turtle.penup()
    turtle.home()

def drawFigure(numTriangles):
    if not 0 < numTriangles < 500:
        exit("Number of triangles is out of range!")

    for _ in range(numTriangles):

        radius = randint(3, 20)
        distance = randint(2, 60)

        turtle.forward(distance)

        while not(radius - BORDER/2 < turtle.xcor() < BORDER/2 - radius and radius - BORDER/2 < turtle.ycor() < BORDER/2 - radius):
            turtle.undo()  # undo last forward()
            turtle.left(37)  # rotate and try again (relative prime angle)
            distance += 1  # increase distance slightly on failure
            turtle.forward(distance)

        angle = randint(1, 360)
        turtle.setheading(angle)

        turtle.right(90)  # turtle represents center so need to adjust
        turtle.forward(radius)  # as turtle.circle() doesn't think that way
        turtle.left(90)

        turtle.pendown()
        turtle.circle(radius, steps=3)
        turtle.penup()

        turtle.left(90)  # undo adjustment to move turtle back to center
        turtle.forward(radius)
        turtle.right(90)

screen = Screen()
screen.tracer(False)

turtle = Turtle()
turtle.speed('fastest')

drawBorder(BORDER)
drawFigure(NUMBER_TRIANGLES)

turtle.hideturtle()

screen.tracer(True)
screen.mainloop()

enter image description here

我将不包括递归等效项,因为这确实不是递归问题。您可以根据自己的作业要求将其强制为一体。