我正在尝试让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
答案 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()
我将不包括递归等效项,因为这确实不是递归问题。您可以根据自己的作业要求将其强制为一体。