TurtleGraphics Python: отбрасывать черепаху от стен?

Итак, я пытаюсь сделать реалистичную функцию отскока, когда черепаха ударяется о стену и отскакивает под соответствующим углом. Мой код выглядит так:

def bounce(num_steps, step_size, initial_heading):
   turtle.reset()
   top = turtle.window_height()/2
   bottom = -top
   right = turtle.window_width()/2
   left = -right

   turtle.left(initial_heading)
   for step in range(num_steps):
      turtle.forward(step_size)
      x, y = turtle.position()
      if left <= x <= right and bottom <= y <= top:
         pass
      else:
         turtle.left(180-2 * (turtle.heading()))

Итак, это работает для боковых стенок, но я не понимаю, как заставить его правильно отскакивать от верха/низа. Какие-либо предложения?


person Community    schedule 21.09.2009    source источник


Ответы (2)


Попробуйте что-то вроде этого:

if not (left <= x <= right):
    turtle.left(180 - 2 * turtle.heading())
elif not (bottom <= y <= top):
    turtle.left(-2 * turtle.heading())
else:
    pass

Мой синтаксис Python немного заржавел, извините: P. Но математика немного отличается для горизонтального и вертикального флипа.

ИЗМЕНИТЬ:

Я подозреваю, что ваша черепаха попадает в ситуацию, когда она указывает вверх и застревает над верхней стеной. Это привело бы к тому, что он просто переворачивался бы на неопределенный срок. Вы можете попробовать добавить следующие условия:

if (x <= left and 90 <= turtle.heading() <= 270) or (right <= x and not 90 <= turtle.heading() <= 270):
    turtle.left(180 - 2 * turtle.heading())
elif (y <= bottom and turtle.heading() >= 180) or (top <= y and turtle.heading <= 180):
    turtle.left(-2 * turtle.heading())
else:
    pass

Если это работает, возможно, в вашем коде есть ошибка. Обработка краев сложна для правильной обработки. Я предполагаю, что Turtle.heading() всегда будет возвращать что-то между 0 и 360 - если нет, то будет еще сложнее сделать правильно.

person We Are All Monica    schedule 22.09.2009
comment
Тем не менее, черепаха все еще висит на верхней стене, но спасибо за попытку. - person ; 22.09.2009
comment
О, обновление: я изменил -2 в Turtle.left под elif, а не на 2, и, похоже, он отскакивает правильно. Спасибо еще раз. - person ; 22.09.2009

Добрый день,

Ваша проблема, похоже, в том, что вы используете одну и ту же тригонометрию для вычисления правой и левой стенок, поскольку вы являетесь верхней и нижней. Листка бумаги и карандаша должно быть достаточно, чтобы рассчитать требуемые прогибы.

def inbounds(limit, value):
    'returns boolean answer to question "is turtle position within my axis limits"'
    return -limit < value * 2 < limit

def bounce(num_steps, step_size, initial_heading):
    '''given the number of steps, the size of the steps 
        and an initial heading in degrees, plot the resultant course
        on a turtle window, taking into account elastic collisions 
        with window borders.
    '''

    turtle.reset()
    height = turtle.window_height()
    width = turtle.window_width()
    turtle.left(initial_heading)

    for step in xrange(num_steps):
        turtle.forward(step_size)
        x, y = turtle.position()

        if not inbounds(height, y):
            turtle.setheading(-turtle.heading())

        if not inbounds(width, x):
            turtle.setheading(180 - turtle.heading())

Я использовал функцию setheading и вспомогательную функцию (inbounds), чтобы дополнительно объявить здесь назначение кода. Предоставление какой-либо строки документа также является хорошей практикой в ​​любом коде, который вы пишете (при условии, что сообщение, которое оно указывает, является точным!!)

Ваш пробег может варьироваться в зависимости от использования xrange, Python 3.0+ переименовывает его в просто range.

person Simon Edwards    schedule 22.09.2009