python - Python海龟图形反复“越界”
问题描述
我试图让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 。
这是显示问题的图片。乌龟应该保持在“边界”(红色方块)内,但会在控制台输出中显示出来
解决方案
您的代码有几个问题。例如,这个边界检查逻辑完全忽略了海龟的当前航向:
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()
我不会包含递归等价物,因为这确实不是递归问题。您可以根据您的任务要求将其强制为一个。
推荐阅读
- javascript - 似乎无法绕过此错误 - “元素不可交互”
- python - 在python中输入多行输入
- jscript - 如何使用 JScript 设置列表值
- python - 在A Point Class Python中计算两点之间的距离
- javascript - Dragula 制作可拖动元素外部的拖动手柄
- vue.js - Storybook 中的 Vue:“SassError:未定义的变量”
- python - 根据 shapefile 掩码获取光栅图像的值
- input - ngx-otp-input 中的自动对焦在 ionic 5 中不起作用
- java - ElasticSearch QueryDSL 到 Java 的转换
- java - inApp 更新,下载但未安装