Created
December 16, 2024 17:01
-
-
Save NikosAlexandris/4cead432137f3a74c5e3ef3a4ddf9377 to your computer and use it in GitHub Desktop.
Modified version of polar_ascii.py
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
# 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