TurtleGraphics Python - 在一个圆圈中限制随机移动的乌龟?

时间:2009-09-20 23:28:51

标签: python turtle-graphics

如何将一只随机移动的乌龟限制在半径为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 个答案:

答案 0 :(得分:1)

你在哪里编码:

   if -width/2 <= x <= width/2 and -height/2 <= y <= height/2:

你的意思是“如果点(x,y)在允许区域内”。因此,当“允许区域”是“半径为50的圆心在原点”时,比较距离和半径的平方(比采用平方根更清楚......! - ),你有:

   if (x*x + y*y) <= 50*50:

保持所有其余代码不变。

编辑:由于OP评论说这对他不起作用我将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”的印刷品,并且乌龟明显被限制在所需的圆圈内,因为逻辑和几何形状也说它必须。

所以我希望OP能够按照这些方式编辑自己的答案(理想情况是在系统和安排中,他可以看到print的结果或其他一些提供输出的方式,并理想地向我们展示)这样我就可以帮他调试他的代码了。

答案 1 :(得分:0)

对此代码的建议修复是否有效的意见分歧引起了我的兴趣。我运行@ user176073的代码与@AlexMartelli的1000步的变化和奇怪的事情确实发生 - 为了说明这一点我添加了一个红色的边界圆圈,乌龟应该留在(大致)内:

enter image description here

flare 发生在多次运行中,似乎与修正逻辑有关,该修正逻辑试图将乌龟一旦离开就将其带回圆圈。乌龟在施加了一个新的角度之后它被错误地应用了 - 它不是原始角度的180°导致乌龟离开圆圈所以它往往会稍微徘徊直到它回到里面。

我尝试了一个新的实现,但有一些变化:在校正之后应用新的角度更新,而不是之前;使用Python 3 turtle的撤消功能将乌龟带回内部而不是自己尝试。这是结果:

enter image description here

更新的代码:

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()