Médio · Bola dentro de um anel giratório

Lição 7: Avançar no tempo passo a passo

Construa em Python o padrão “Bola dentro de um anel giratório” e aprenda pelo caminho:

  • uma simulação: pequenos passos de tempo num loop while
  • vetores como arrays numpy
  • o produto escalar e uma reflexão
  • ângulos com np.arctan2, reduzidos a uma volta
  • break para sair de um loop

Veja-o primeiro

É reproduzido a partir do YouTube depois de um clique.

spinning-ring.py
"""A ball under gravity in a ring with a gap that spins; the bounces are elastic and without friction.
Run: python spinning-ring.py   (needs: pip install numpy matplotlib)
"""
import numpy as np
import matplotlib.pyplot as plt

plt.style.use("dark_background")

R, ball, g = 1.0, 0.05, 9.81  # ring radius (m), ball radius, gravity
gap, spin = np.radians(18), 2 * np.pi / 4  # an 18 degree gap, one turn every 4 seconds
p, v = np.array([0.3, 0.2]), np.array([1.8, 0.7])
dt, t, track = 0.0005, 0.0, []

while t < 60:
    v[1] -= g * dt
    p = p + v * dt
    t += dt
    track.append(p.copy())
    r = np.linalg.norm(p)
    if r > R - ball:  # the ball touches the wall, or is at the gap
        angle = np.arctan2(p[1], p[0])
        centre = -np.pi / 2 + spin * t  # where the gap is now
        off = abs((angle - centre + np.pi) % (2 * np.pi) - np.pi)
        if off < gap / 2 - ball / R:  # all of the ball fits through: out
            break
        normal = p / r
        v = v - 2 * np.dot(v, normal) * normal  # the bounce: the spin plays no part in it
        p = normal * (R - ball)

track = np.array(track)
print(f"escaped after {t:.1f} s" if t < 60 else "still inside after 60 s")
plt.figure(figsize=(6, 6))
plt.plot(track[:, 0], track[:, 1], color="#5eead4", linewidth=0.4)
plt.gca().add_patch(plt.Circle((0, 0), R, fill=False, color="white"))
plt.axis("equal")
plt.axis("off")
plt.show()

# Try: spin = 0 and centre = -np.pi / 2 (a still gap at the bottom): the bounces stay the same

Não tem Python neste computador? O notebook executa o mesmo script, os exercícios e as respostas no navegador, no Google Colab. O notebook está em inglês.

Linha a linha

  1. v[1] -= g * dt

    A gravidade: a cada passo, a velocidade vertical diminui em g·dt.

  2. p = p + v * dt

    O deslocamento da bola é a sua velocidade vezes o passo de tempo. Esta forma mais simples de avançar chama-se método de Euler.

  3. if r > R - ball:

    A borda da bola chega à parede quando o seu centro está a um raio da bola do anel.

  4. off = abs((angle - centre + np.pi) % (2 * np.pi) - np.pi)

    O ângulo entre a bola e o meio da abertura, reduzido ao intervalo −π … π, para que 359° conte como 1° de distância.

  5. v = v - 2 * np.dot(v, normal) * normal

    A reflexão: retirar duas vezes a parte da velocidade ao longo da normal. A rotação do anel não entra nela.

  6. p = normal * (R - ball)

    Pôr a bola de volta na parede, para que um passo nunca a deixe do lado de fora.

Experimente

  1. Verifique a energia, ½·|v|² + g·y por unidade de massa: mostre-a no início e no fim. Mantém-se igual?

    Pista

    np.dot(v, v) é |v|².

    Resposta

    Quase: diminui cerca de 2% ao longo da execução, de 3,83 para 3,75. Os passos simples e o empurrão de volta para a parede perdem um pouco.

  2. Reduza dt a metade. O que acontece à energia e ao momento em que a bola escapa?

    Pista

    dt = 0.00025.

    Resposta

    A energia passa a diminuir cerca de 1% em vez de 2%; a bola ainda escapa após cerca de 3,9 s.

  3. Por que razão a linha do ricochete nem sequer usa spin?

    Pista

    Em que direção se move um ponto da parede?

    Resposta

    Sem atrito, a parede só pode empurrar ao longo da normal, e uma parede que gira move-se ao longo da tangente, em ângulo reto com ela.

Quiz

1. O que mede np.dot(v, normal)?
2. O que faz break no loop while?
3. Que intervalo devolve np.arctan2(y, x)?
4. Por que razão passos de tempo menores melhoram a simulação?
5. O que muda a rotação do anel?

Flashcards

Leia a frente, tente recordar o verso e só depois abra o cartão.

  • Passo de Euler

    posição += velocidade · dt; velocidade += aceleração · dt.

  • Reflexão

    v − 2·(v · n)·n, com n a normal unitária da parede.

  • np.arctan2(y, x)

    O ângulo do ponto (x, y), de −π a π.

  • break

    Sai imediatamente do loop em que está.

  • Verificação da energia

    ½·|v|² + g·y deve manter-se quase constante sem atrito: um teste de uma simulação.

Estes flashcards numa página à parte →