65 lines
2.3 KiB
Python
Executable File
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])
|