# Vorschau der Ventilator-Kandidaten ohne Browser: Bezier-Segmente abtasten, # rotieren, mit Pillow fuellen. Rechts jeweils die 22-px-Miniatur (Originalgroesse). import math from PIL import Image, ImageDraw BG, FG, CASE = "#1d222a", "#e8804c", "#6f5344" def bez(p0, p1, p2, p3, n=80): for i in range(n + 1): t = i / n u = 1 - t yield (u**3 * p0[0] + 3 * u * u * t * p1[0] + 3 * u * t * t * p2[0] + t**3 * p3[0], u**3 * p0[1] + 3 * u * u * t * p1[1] + 3 * u * t * t * p2[1] + t**3 * p3[1]) def outline(segs): pts = [] for s in segs: pts.extend(bez(*s)) return pts def rot(p, deg, c=12.0): a = math.radians(deg) x, y = p[0] - c, p[1] - c return (c + x * math.cos(a) - y * math.sin(a), c + x * math.sin(a) + y * math.cos(a)) def draw(segs, blades, case_r, hub_r, size): S = size / 24 img = Image.new("RGB", (size, size), BG) d = ImageDraw.Draw(img) if case_r: d.ellipse([(12 - case_r) * S, (12 - case_r) * S, (12 + case_r) * S, (12 + case_r) * S], outline=CASE, width=max(1, int(1.4 * S))) pts = outline(segs) step = 360 / blades for i in range(blades): d.polygon([(x * S, y * S) for x, y in (rot(p, i * step) for p in pts)], fill=FG) d.ellipse([(12 - hub_r) * S, (12 - hub_r) * S, (12 + hub_r) * S, (12 + hub_r) * S], fill=BG, outline=FG, width=max(1, int(1.5 * S))) return img CANDS = { "A_komma4": (4, [((12, 12), (11.4, 8.6), (11.4, 5.4), (12.7, 3.1)), ((12.7, 3.1), (15.6, 4.2), (18.2, 6.6), (18.9, 9.4)), ((18.9, 9.4), (17.2, 11.2), (14.6, 12), (12, 12))]), "B_schlank4": (4, [((12, 12), (10.6, 9), (10.4, 5.6), (12.2, 3.4)), ((12.2, 3.4), (14.8, 4.6), (17.2, 7.2), (17.6, 10)), ((17.6, 10), (16, 11.6), (13.8, 12.2), (12, 12))]), "C_breit3": (3, [((12, 12), (10.9, 8.4), (11.2, 4.8), (13.3, 2.9)), ((13.3, 2.9), (16.6, 4.4), (18.8, 7.4), (19.2, 10.6)), ((19.2, 10.6), (17, 12), (14.2, 12.4), (12, 12))]), "D_sichel5": (5, [((12, 12), (11.2, 9), (11.3, 5.8), (12.9, 3.6)), ((12.9, 3.6), (15.1, 5), (16.9, 7.4), (17.3, 10.1)), ((17.3, 10.1), (15.8, 11.4), (13.9, 12.1), (12, 12))]), } pad = 12 big, small = 200, 22 W = pad + len(CANDS) * (big + pad) sheet = Image.new("RGB", (W, big + small + 3 * pad), BG) dr = ImageDraw.Draw(sheet) for i, (name, (blades, segs)) in enumerate(CANDS.items()): x = pad + i * (big + pad) sheet.paste(draw(segs, blades, 10.4, 2.1, big), (x, pad)) sheet.paste(draw(segs, blades, 10.4, 2.1, small), (x + big // 2 - small // 2, big + 2 * pad)) dr.text((x + 4, big + 2 * pad + small + 2), name, fill="#98a2b3") sheet.save("fan_preview.png") print("ok")