0

我怎样才能让一个随机移动的乌龟被限制在一个半径为 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)

此代码适用于屏幕中的海龟,但不适用于圆形。

4

2 回答 2

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)

bounded_random_walk(200, 10, 30)从 Mac OS X 上的 Terminal.App 运行它,这样print就会显示出来。结果是我得到了大约 50 到 60 个“反弹”的打印,并且乌龟显然被限制在所需的圆圈内,因为逻辑和几何也说它必须。

因此,我希望 OP 将按照这些思路编辑他们自己的答案(理想情况下,在系统上和安排中,他可以看到结果print或以其他方式提供输出并理想地向我们展示),以便我可以帮助他调试他的代码。

于 2009-09-20T23:45:25.130 回答
0

关于此代码的建议修复是否有效的意见分歧引起了我的兴趣。我用@AlexMartelli 的更改运行@user176073 的代码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()
于 2016-12-05T04:49:18.927 回答