Intermedio · Bola en un anillo giratorio

Lección 7: Avanzar en el tiempo

Construye en Python el patrón «Bola en un anillo giratorio» y aprende por el camino:

  • una simulación: pasos de tiempo pequeños en un bucle while
  • vectores como arrays de numpy
  • el producto escalar y una reflexión
  • ángulos con np.arctan2, reducidos a una vuelta
  • break para salir de un bucle

Míralo primero

Se reproduce desde YouTube tras hacer clic.

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

¿No tienes Python en este equipo? El cuaderno ejecuta el mismo script, los ejercicios y las respuestas en tu navegador, en Google Colab. El cuaderno está en inglés.

Línea a línea

  1. v[1] -= g * dt

    La gravedad: en cada paso, la velocidad vertical baja en g·dt.

  2. p = p + v * dt

    La bola se mueve su velocidad multiplicada por el paso de tiempo. Esta forma de avanzar, la más sencilla, se llama método de Euler.

  3. if r > R - ball:

    El borde de la bola llega a la pared cuando su centro está a un radio de bola del anillo.

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

    El ángulo entre la bola y el centro de la abertura, reducido al intervalo −π … π, para que 359° cuente como 1° de distancia.

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

    La reflexión: resta dos veces la parte de la velocidad a lo largo de la normal. El giro del anillo no interviene.

  6. p = normal * (R - ball)

    Devuelve la bola a la pared, para que un paso nunca pueda dejarla fuera.

Pruébalo tú

  1. Comprueba la energía, ½·|v|² + g·y por unidad de masa: muéstrala al principio y al final. ¿Se mantiene igual?

    Pista

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

    Respuesta

    Casi: baja alrededor de un 2 % a lo largo de la ejecución, de 3.83 a 3.75. Los pasos sencillos y el empujón de vuelta a la pared pierden un poco.

  2. Divide dt entre dos. ¿Qué les pasa a la energía y al momento en que escapa la bola?

    Pista

    dt = 0.00025.

    Respuesta

    Ahora la energía baja alrededor de un 1 % en lugar de un 2 %; la bola sigue escapando tras unos 3,9 s.

  3. ¿Por qué la línea del rebote no usa spin para nada?

    Pista

    ¿Hacia dónde se mueve un punto de la pared?

    Respuesta

    Sin rozamiento, la pared solo puede empujar a lo largo de la normal, y una pared que gira se mueve a lo largo de la tangente, perpendicular a ella.

Cuestionario

1. ¿Qué mide np.dot(v, normal)?
2. ¿Qué hace break en el bucle while?
3. ¿Qué rango devuelve np.arctan2(y, x)?
4. ¿Por qué los pasos de tiempo más pequeños mejoran la simulación?
5. ¿Qué cambia el giro del anillo?

Tarjetas de repaso

Lee el anverso, di el reverso para ti y luego abre la tarjeta.

  • Paso de Euler

    posición += velocidad · dt; velocidad += aceleración · dt.

  • Reflexión

    v − 2·(v · n)·n, con n la normal unitaria de la pared.

  • np.arctan2(y, x)

    El ángulo del punto (x, y), de −π a π.

  • break

    Sale del bucle en el que está, de inmediato.

  • Comprobación de la energía

    ½·|v|² + g·y debería mantenerse casi constante sin rozamiento: una prueba de una simulación.

Estas tarjetas en su propia página →