Created
August 14, 2025 20:24
-
-
Save tonyreina/013afd8be4be44e905619080071fe860 to your computer and use it in GitHub Desktop.
Creates an animation of a snake-like monster.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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