Skip to content

Instantly share code, notes, and snippets.

@tonyreina
Created August 14, 2025 20:24
Show Gist options
  • Save tonyreina/013afd8be4be44e905619080071fe860 to your computer and use it in GitHub Desktop.
Save tonyreina/013afd8be4be44e905619080071fe860 to your computer and use it in GitHub Desktop.
Creates an animation of a snake-like monster.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# --- Precompute x and y (Mathematica: x = N@Range[10000]; y = x/235.) ---
x = np.arange(1, 10001, dtype=np.float64)
y = x / 235.0
def pts(t: float) -> np.ndarray:
"""
Vectorized translation of the Mathematica pts[t_] function.
Returns an (N, 2) array of point coordinates.
"""
k = (4.0 + 3.0 * np.sin(2.0 * y - t)) * np.cos(x / 29.0)
e = y / 8.0 - 13.0
d = np.sqrt(k * k + e * e)
c = d - t
# q = 3 Sin[2 k] + 0.3/k + Sin[y/25.] k (9 + 4 Sin[9 e - 3 d + 2 t])
# Safely handle division by zero in 0.3/k:
inv_k = np.divide(0.3, k, out=np.zeros_like(k), where=(k != 0))
q = 3.0 * np.sin(2.0 * k) + inv_k + np.sin(y / 25.0) * k * (9.0 + 4.0 * np.sin(9.0 * e - 3.0 * d + 2.0 * t))
X = q + 30.0 * np.cos(c) + 200.0
Y = 400.0 - (q * np.sin(c) + 39.0 * d - 220.0)
return np.column_stack((X, Y))
# --- Figure setup ---
fig, ax = plt.subplots(figsize=(6, 6))
ax.set_facecolor("black")
ax.set_xlim(70, 330)
ax.set_ylim(30, 350)
ax.set_xticks([])
ax.set_yticks([])
ax.set_title("Auto-animated Mathematica sketch → Python", color="white", pad=12)
# Initial scatter
coords0 = pts(0.0)
sc = ax.scatter(coords0[:, 0], coords0[:, 1], s=1.0, c="white", alpha=0.65, edgecolors="none")
# --- Animation ---
frames = 300 # number of frames in one loop
t_values = np.linspace(0.0, 2.0 * np.pi, frames, endpoint=False)
def update(frame_idx):
t = t_values[frame_idx]
sc.set_offsets(pts(t))
return (sc,) # artist tuple
ani = FuncAnimation(
fig,
update,
frames=np.arange(frames),
interval=33, # ~30 FPS
repeat=True,
blit=False # set True if your backend supports blitting for faster updates
)
# To save (optional), uncomment one of the following lines:
# ani.save("manipulate_animation.mp4", writer="ffmpeg", fps=30, dpi=150)
ani.save("manipulate_animation.gif", writer="pillow", fps=20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment