Opus/2026.02.16-Devotion/video/labyrinth/turtle.py
2026-07-04 09:09:13 -07:00

65 lines
2.3 KiB
Python
Executable File

import math
import json
import sys
def get_cartesian(r_idx, c_idx, n_radii, n_circles, center, size):
# Padding to keep it off the very edge
max_radius = (size / 2) - 40
# Radius calculation: C=0 is the innermost, n_circles-1 is outermost
# We add 1 to c_idx to ensure we don't start exactly at the origin (0,0)
ring_step = max_radius / n_circles
r_pixel = (c_idx + 1) * ring_step
# Angle calculation: 0 is 3 o'clock, moving counter-clockwise
angle_rad = math.radians(r_idx * (360.0 / n_radii))
x = center + r_pixel * math.cos(angle_rad)
y = center + r_pixel * math.sin(angle_rad)
return x, y
def render_polar(json_path, output_path):
with open(json_path, 'r') as f:
data = json.load(f)
n_radii = data["n_radii"]
n_circles = data["n_circles"]
vertices = data["vertices"]
center, size = 500, 1000
# Initial State
curr_r, curr_c = 0, 0
x, y = get_cartesian(curr_r, curr_c, n_radii, n_circles, center, size)
path_d = [f"M {x},{y}"]
for move in vertices:
if move == ">": curr_r = (curr_r + 1) % n_radii
elif move == "<": curr_r = (curr_r - 1) % n_radii
elif move == "v": curr_c = max(0, curr_c - 1)
elif move == "^": curr_c = min(n_circles - 1, curr_c + 1)
new_x, new_y = get_cartesian(curr_r, curr_c, n_radii, n_circles, center, size)
if move in [">", "<"]:
# Ring radius for the SVG Arc
r_px = (curr_c + 1) * ((size / 2 - 40) / n_circles)
# Sweep: 1 for clockwise (>), 0 for counter-clockwise (<)
sweep = 1 if move == ">" else 0
path_d.append(f"A {r_px},{r_px} 0 0 {sweep} {new_x},{new_y}")
else:
# Straight radial line
path_d.append(f"L {new_x},{new_y}")
svg = f'<svg viewBox="0 0 {size} {size}" xmlns="http://www.w3.org/2000/svg" style="background:white;">'
# Optional: Draw the grid for reference
svg += f'<path d="{" ".join(path_d)}" fill="none" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>'
svg += '</svg>'
with open(output_path, 'w') as f:
f.write(svg)
print(f"✅ Path rendered using {n_radii} radii and {n_circles} circles.")
if __name__ == "__main__":
render_polar(sys.argv[1], sys.argv[2])