Skip to content

Instantly share code, notes, and snippets.

@NikosAlexandris
Created December 16, 2024 17:01
Show Gist options
  • Save NikosAlexandris/4cead432137f3a74c5e3ef3a4ddf9377 to your computer and use it in GitHub Desktop.
Save NikosAlexandris/4cead432137f3a74c5e3ef3a4ddf9377 to your computer and use it in GitHub Desktop.
Modified version of polar_ascii.py
# Based on [polar_ascii.py](https://github.com/tfpgh/polar_ascii/blob/214229c66c554335fb35c535ff2fb768102e4da4/polar_ascii.py)
import importlib.util
import math
import os
import sys
# number of points per degree in the domain
ITERATION_MULTIPLE = 10
SCALE_DIVISOR = 6
# Ensure script is called with path to equation file
if len(sys.argv) != 2:
raise ValueError("Script must be called with one and only one argument")
# Load equation file
spec = importlib.util.spec_from_file_location("equation", sys.argv[1])
if spec is None:
raise ValueError("Invalid file provided")
equation = importlib.util.module_from_spec(spec)
sys.modules["equation"] = equation
loader = spec.loader
if loader is None:
raise ValueError("Invalid file provided")
loader.exec_module(equation)
# Generate raw cartesian points from equation file
raw_points: list[tuple[float, float]] = []
inc_count = (
ITERATION_MULTIPLE
* int((equation.domain[1] - equation.domain[0]) * (180.0 / math.pi))
+ 1
)
for inc in range(inc_count):
theta = (
(inc / inc_count) * (equation.domain[1] - equation.domain[0])
) + equation.domain[0]
r = equation.r(theta)
cart_point = (r * math.cos(theta), r * math.sin(theta))
raw_points.append(cart_point)
# Get the min/max values for x and y
x_min = float(min(raw_points, key=lambda point: point[0])[0])
x_max = float(max(raw_points, key=lambda point: point[0])[0])
y_min = float(min(raw_points, key=lambda point: point[1])[1])
y_max = float(max(raw_points, key=lambda point: point[1])[1])
x_range = x_max - x_min
y_range = y_max - y_min
terminal_size = os.get_terminal_size()
# terminal_columns, terminal_lines = shutil.get_terminal_size() # we don't need lines!
# terminal_length = int(terminal_columns * terminal_width_fraction) # Will this work ?
# Cells have a width of two characers. Adjust for double-width
# characters and add padding, remove one line to make room for new terminal
# prompt.
# grid_size = (terminal_size.columns // 2, terminal_size.lines - 1)
grid_size = (terminal_size.columns // 2 - 2, terminal_size.lines - 2)# New ---
# scale = min(grid_size[0] / x_min_max_diff, grid_size[1] / y_min_max_diff)
# Calculate scale and maintain aspect ratio
scale_x = grid_size[0] / x_range
scale_y = grid_size[1] / y_range
scale = min(scale_x, scale_y) / SCALE_DIVISOR
# Centering offsets
x_offset = (grid_size[0] - (x_range * scale)) / 2
y_offset = (grid_size[1] - (y_range * scale)) / 2
# Scale and translate points
final_points = []
for point in raw_points:
new_x = ((point[0] - x_min) * scale) + x_offset
new_y = ((point[1] - y_min) * scale) + y_offset
final_points.append((new_x, new_y))
# Create an empty grid
grid = [[False] * grid_size[0] for _ in range(grid_size[1])]
# Populate the grid with points
for point in final_points:
try:
grid[int(point[1])][int(point[0])] = True
except IndexError:
# print("Hit bound, cont.")
continue # Ignore points outside the grid
# Print the grid
for row in grid:
for cell in row:
if cell:
print("@ ", end="")
else:
print(" ", end="")
print("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment