69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
import math
|
|
import numpy as np
|
|
from PIL import Image, ImageDraw
|
|
|
|
SIZE = 1024
|
|
CENTER = SIZE / 2.0
|
|
R_RING = SIZE * 0.082
|
|
|
|
img = Image.new('RGBA', (SIZE, SIZE), (10, 10, 20, 255))
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Проверяем монолитный стык без углов
|
|
for k in range(3):
|
|
rot = -math.pi / 2.0 + k * (2.0 * math.pi / 3.0)
|
|
spine = []
|
|
widths = []
|
|
|
|
# Стартуем глубже внутри дуги кольца, чтобы стык был абсолютно гладким
|
|
steps_in_ring = 30
|
|
for s in range(steps_in_ring):
|
|
t = s / float(steps_in_ring)
|
|
ang = (rot - 0.45) + t * 0.45
|
|
rad = R_RING
|
|
px = CENTER + rad * math.cos(ang)
|
|
py = CENTER + rad * math.sin(ang)
|
|
spine.append((px, py))
|
|
widths.append(24.0)
|
|
|
|
# Плавный тангенциальный сход (производная по радиусу в точке схода строго равна 0)
|
|
steps_out = 70
|
|
for s in range(1, steps_out):
|
|
u = s / float(steps_out - 1)
|
|
ang = rot + u * 1.68
|
|
# u^1.8 дает строго нулевую радиальную производную в начале
|
|
rad = R_RING + (u**1.6) * (SIZE * 0.150)
|
|
px = CENTER + rad * math.cos(ang)
|
|
py = CENTER + rad * math.sin(ang)
|
|
spine.append((px, py))
|
|
w = 24.0 * (1.0 - (u**0.85) * 0.88)
|
|
widths.append(max(2.0, w))
|
|
|
|
left = []
|
|
right = []
|
|
for i in range(len(spine)):
|
|
p = spine[i]
|
|
w = widths[i] / 2.0
|
|
if i == 0:
|
|
dx = spine[1][0] - p[0]
|
|
dy = spine[1][1] - p[1]
|
|
elif i == len(spine) - 1:
|
|
dx = p[0] - spine[i-1][0]
|
|
dy = p[1] - spine[i-1][1]
|
|
else:
|
|
dx = spine[i+1][0] - spine[i-1][0]
|
|
dy = spine[i+1][1] - spine[i-1][1]
|
|
length = math.hypot(dx, dy) + 1e-6
|
|
nx = -dy / length
|
|
ny = dx / length
|
|
left.append((p[0] + nx * w, p[1] + ny * w))
|
|
right.append((p[0] - nx * w, p[1] - ny * w))
|
|
|
|
poly = left + right[::-1]
|
|
draw.polygon(poly, fill=(255, 220, 80, 255))
|
|
|
|
# Центральное кольцо сливается с лентами
|
|
draw.ellipse([CENTER - R_RING, CENTER - R_RING, CENTER + R_RING, CENTER + R_RING], outline=(255, 220, 80, 255), width=24)
|
|
img.save('/home/alexives/.gemini/antigravity-ide/brain/4ff924d9-3d7f-4202-9066-3ac5c3088b8e/scratch/test_junction.png')
|
|
print("Saved test junction!")
|