Ответ 1
dx, dy = -dy, dx
В случае сомнений примените математику.;)
Мне нужно записать эти четыре if
в Python. Обратите внимание, что он делает, меняется между четырьмя возможными состояниями в цикле: 1,0 -> 0,1 -> -1,0 -> 0,-1
и назад к первому.
if [dx, dy] == [1,0]:
dx, dy = 0, 1
if [dx, dy] == 0, 1:
dx, dy = -1, 0
if [dx, dy] == [-1, 0]
dx, dy = 0, -1
if [dx, dy] == [0, -1]:
dx, dy = 1, 0
Может ли кто-нибудь предложить мне лучший/лучший способ написать это?
dx, dy = -dy, dx
В случае сомнений примените математику.;)
Предложение Магнуса, несомненно, правильный ответ на ваш вопрос, поставленный, но вообще говоря, вы хотите использовать словарь для таких проблем, как это:
statemap = {(1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0)}
dx, dy = statemap[dx, dy]
Даже в этом случае я мог бы лучше использовать словарь, так как ясно, что существует ровно четыре состояния и они повторяются, но трудно противостоять чистой красоте всех математик.
Кстати, у кода в вашем вопросе есть ошибка, и, считая, что значения, которые вы тестируете, являются единственными возможными значениями, эквивалентны:
dx, dy = 1, 0
Ошибка в том, что вам нужно elif
для второго и последующих условий, иначе вы продолжите тестирование dx
и dy
после их изменения. Если они 1
и 0
, тогда все ваши условия будут истинными, и в конце концов они останутся одинаковыми! Если они начинаются как 0
и 1
, тогда второе и все последующие условия будут истинными, и вы снова получите 1, 0
. И так далее...
Просто протягивая Магнуса ответ. Если вы представляете [dx, dy] в качестве вектора, то, что вы на самом деле делаете, это rotation 90 градусов (или PI/2).
Чтобы вычислить это, вы можете использовать следующее преобразование:
Что в вашем случае перевести на:
x = x * cos(90) - y * sin(90)
y = x * sin(90) + y * cos(90)
Так как sin(90) = 1
и cos(90) = 0
, мы упрощаем его:
x, y = -y, x
И вот он у вас есть!
Значения, с которыми вы работаете, выглядят как единичный вектор, который непрерывно вращается - другими словами, phasor. Сложные числа - это координаты, поэтому:
# at initialization
phase = 1
# at the point of modification
phase *= 1j
dx, dy = phase.real, phase.imag
Предполагая, что моя интерпретация значения значений dx, dy верна, это дает вам дополнительную гибкость в случае, если впоследствии окажется, что вы хотите повернуть на какую-то другую сумму на каждом шаге.
Хотя я бы пошел с ответом Магнуса, вот еще один подход к вращению над набором значений:
def rotate(*states):
while 1:
for state in states:
yield state
for dx, dy in rotate((1, 0), (0, 1), (-1, 0), (0, -1)):
pass
Обратите внимание, что в цикле for dx, dy
должен быть break
, иначе он никогда не закончится.