colors/scripts/scatter.py

149 lines
4.4 KiB
Python
Raw Normal View History

import matplotlib.patches as patches
import matplotlib.pyplot as plt
import numpy as np
from pathlib import Path
def get_quadrant(x, y):
"""Return the quadrant of a given point."""
if x >= 0 and y >= 0:
return 1
elif x < 0 and y >= 0:
return 2
elif x < 0 and y < 0:
return 3
else:
return 4
def is_overlapping(x, y, existing_points, radius):
"""Check if a point overlaps with existing points, crosses a quadrant or goes beyond the quadrant lines."""
current_quadrant = get_quadrant(x, y)
buffer = 0.25
# Check if circle touches/crosses the x=0 or y=0 lines.
if (
abs(x) + radius > buffer
and abs(x) - radius < buffer
or abs(y) + radius > buffer
and abs(y) - radius < buffer
):
return True
for ex, ey in existing_points:
# Check overlap with existing points
if np.sqrt((x - ex) ** 2 + (y - ey) ** 2) <= 2 * radius + 0.5:
return True
# Check if the circle touches another quadrant
if (
get_quadrant(ex, ey) != current_quadrant
and np.sqrt((x - ex) ** 2 + (y - ey) ** 2) <= radius
):
return True
return False
DIR = "/teamspace/studios/this_studio/out_sortcolors"
N = 100
DPI = 300
SIZE = 72 # canvas size?
radius = 3
variance = 72 # Adjust variance as needed
Path(DIR).mkdir(exist_ok=True, parents=True)
with open(f"{DIR}/arrangement_grid.txt", "w") as f:
radius = 3
half = SIZE / 2 - 4
# make points an equispaced grid of 10 x 10 ranging from [-35, 35]
interval = (half - (-half)) / 9 # 10 points, so 9 intervals
# Generate the grid points
points = [
(x, y)
for x in np.arange(-half, half + 0.1, interval)
for y in np.arange(-half, half + 0.1, interval)
]
for x, y in points:
f.write(f"{x-radius}, {y+radius}\n")
# f.write(f"{x}, {y}\n")
print("wrote grid")
for seed in range(11, 22):
try:
np.random.seed(seed)
# To store plotted points
points = []
max_iterations = int(1e7)
iterations = 0
# Generate points
for k in range(N):
while True:
# x, y = np.random.normal(0, variance), np.random.normal(0, variance)
random_angle = np.random.uniform(0, 2 * np.pi)
# random_radius = np.random.uniform(0.25+radius, SIZE/2 - radius - 0.25)
random_radius = abs(np.random.normal(0, variance))
x = random_radius * np.cos(random_angle)
y = random_radius * np.sin(random_angle)
iterations += 1
if not is_overlapping(x, y, points, radius):
if max(abs(x), abs(y)) + radius < SIZE / 2 - 0.25:
points.append((x, y))
break
if iterations > max_iterations:
raise ValueError(f"Too many iterations: {k} points")
print(f"{k}: ({x}, {y}) @ {iterations:09d}")
# Create plot with circles
fig, ax = plt.subplots(1, 1, figsize=(SIZE, SIZE))
for x, y in points:
circle = patches.Circle((x, y), radius, color="black")
ax.add_patch(circle)
# Draw the standard quadrants
ax.axhline(0, color="black", linewidth=0.5)
ax.axvline(0, color="black", linewidth=0.5)
# Use square axis and set limits
lim_x = (
max(
abs(max(points, key=lambda t: t[0])[0]),
abs(min(points, key=lambda t: t[0])[0]),
)
+ radius
)
lim_y = (
max(
abs(max(points, key=lambda t: t[1])[1]),
abs(min(points, key=lambda t: t[1])[1]),
)
+ radius
)
lim_x = lim_y = SIZE / 2
ax.axis("off")
ax.set_aspect("equal")
ax.set_xlim(-lim_x, lim_x)
ax.set_ylim(-lim_y, lim_y)
# Save and show
fig.tight_layout(pad=0)
plt.savefig(
f"{DIR}/arrangement_{seed}.png", dpi=DPI, bbox_inches="tight", pad_inches=0
)
# plt.show()
# also save x/y coords as text file
with open(f"{DIR}/arrangement_{seed}.txt", "w") as f:
for x, y in points:
f.write(f"{x-radius}, {y+radius}\n")
# f.write(f"{x}, {y}\n")
except ValueError as e:
print(f"{seed}: {e}")
except AssertionError as e:
print(f"{seed}: {e}")