TurtleGraphics Python - 如何限制随机移动的海龟在圆形内?
我想让一只随机移动的乌龟在一个半径为50的圆圈里活动,这个圆的中心在(0, 0)的位置。也就是说,如果乌龟现在在(x, y)这个位置,它离中心的距离可以用公式 math.sqrt(x ** 2 + y ** 2) 来计算。每当乌龟离中心的距离超过50时,就让它转身继续移动。我已经让代码在屏幕大小上工作得很好,但我该把 math.sqrt(x ** 2 + y ** 2) 放在哪里,才能让它限制在圆圈里呢?以下是我目前的代码:
import turtle, random, math
def bounded_random_walk(num_steps, step_size, max_turn):
turtle.reset()
width = turtle.window_width()
height = turtle.window_height()
for step in range(num_steps):
turtle.forward(step_size)
turn = random.randint(-max_turn, max_turn)
turtle.left(turn)
x, y = turtle.position()
if -width/2 <= x <= width/2 and -height/2 <= y <= height/2:
pass
else: # turn around!
turtle.left(180)
turtle.forward(step_size)
这段代码在屏幕上能让乌龟活动,但不能限制在圆圈内。
2 个回答
关于这个代码的修复建议是否有效,大家的看法不一,这引起了我的兴趣。我用@user176073的代码和@AlexMartelli的修改进行了1000步的测试,结果出现了一些奇怪的现象。为了说明这一点,我在图中加了一个红色的边界圆圈,海龟应该大致保持在这个圆圈内:
在多次运行中,出现了所谓的闪烁现象,这似乎和修正逻辑有关。这个逻辑试图把海龟拉回圆圈,但在海龟改变了角度之后错误地应用了这个逻辑。它并不是把海龟从圆圈外拉回的原始角度的180度,所以海龟会有点游荡,直到回到圆圈内。
我尝试了一个新的实现,做了一些改动:在修正之后再应用新的角度更新,而不是之前;使用Python 3海龟的撤销功能来让海龟回到圆圈内,而不是自己去做。结果如下:
更新后的代码:
import turtle
import random
RADIUS = 50
def bounded_random_walk(num_steps, step_size, max_turn):
for _ in range(num_steps):
turtle.forward(step_size)
x, y = turtle.position()
if (x * x + y * y) > RADIUS * RADIUS:
turtle.undo() # undo misstep
turtle.left(180)
turn = random.randint(-max_turn, max_turn)
turtle.left(turn)
bounded_random_walk(1000, 10, 30)
turtle.exitonclick()
你在编写代码的地方:
if -width/2 <= x <= width/2 and -height/2 <= y <= height/2:
你其实是想说“如果点(x, y)在允许的区域内”。所以,当“允许的区域”是“以原点为中心,半径为50的圆”时,比较距离的平方和半径(这样比开平方要简单明了得多...!)你会得到:
if (x*x + y*y) <= 50*50:
其他代码保持不变。
编辑:因为提问者评论说这个对他没用,我把if/else改成了:
x, y = turtle.position()
# if -width/3 <= x <= width/3 and -height/3 <= y <= height/3:
if (x*x + y*y) <= 50*50:
pass
else: # turn around!
print 'Bounce', step, x, y
turtle.left(180)
turtle.forward(step_size)
然后在Mac OS X的Terminal.App中运行了bounded_random_walk(200, 10, 30)
,这样print
的结果就能显示出来。结果是我大约得到了50到60次“Bounce”的输出,海龟明显被限制在了想要的圆内,这也是逻辑和几何所说的。
所以我希望提问者能根据这些建议修改自己的回答(最好是在一个能看到print
结果的系统和环境中,或者用其他方式输出结果,并且最好能展示给我们看),这样我就可以帮助他调试代码。