add blobs

This commit is contained in:
julius 2024-10-27 21:43:34 +01:00
parent 651473975f
commit b97737f670
Signed by: julius
GPG Key ID: C80A63E6A5FD7092
3 changed files with 63 additions and 3 deletions

View File

@ -32,10 +32,10 @@ with open("popular.json", "r") as f:
palettes += json.load(f) palettes += json.load(f)
palette = random.choice(palettes) palette = random.choice(palettes)
enabled_markers = "otY+xP*" enabled_markers = "otY+xP*b"
markers = random.choices(enabled_markers, k=random.randint(1, len(enabled_markers))) markers = random.choices(enabled_markers, k=random.randint(1, len(enabled_markers)))
for i, palette in enumerate(palettes): for i, palette in enumerate(palettes):
colours = ["black"] + palette["colours"] colours = ["none"] + palette["colours"]
b = make_wallpaper( b = make_wallpaper(
",".join(colours), ",".join(colours),
fileformat="png", fileformat="png",

57
blob.py Normal file
View File

@ -0,0 +1,57 @@
import svg
from typing import Iterator, NamedTuple
import numpy as np
RGen = np.random.default_rng()
class Point(NamedTuple):
x: float
y: float
def iter_body_points(size: int) -> Iterator[Point]:
n_points = RGen.integers(3, 12) # how many points do we want?
angle_step = (
np.pi * 2 / n_points
) # step used to place each point at equal distances
for point_number in range(1, n_points + 1):
pull = 0.75 * RGen.random() * 0.25
angle = point_number * angle_step
x = size + np.cos(angle) * size * pull
y = size + np.sin(angle) * size * pull
yield Point(x, y)
def spline(points: list[Point], body_tension: int) -> Iterator[svg.PathData]:
"""
https://github.com/georgedoescode/splinejs
"""
yield svg.MoveTo(*points[-1])
first_point = points[0]
second_point = points[1]
points.insert(0, points[-1])
points.insert(0, points[-2])
points.append(first_point)
points.append(second_point)
for p0, p1, p2, p3 in zip(points, points[1:], points[2:], points[3:]):
yield svg.CubicBezier(
x1=p1.x + (p2.x - p0.x) / 6 * body_tension,
y1=p1.y + (p2.y - p0.y) / 6 * body_tension,
x2=p2.x - (p3.x - p1.x) / 6 * body_tension,
y2=p2.y - (p3.y - p1.y) / 6 * body_tension,
x=p2.x,
y=p2.y,
)
def blob(x, y, c, s, body_tension: int = 1) -> svg.Path:
points = list(iter_body_points(s))
return svg.Path(
d=list(spline(points, body_tension)),
fill=c,
stroke="#000000",
stroke_width=2,
transform=[svg.Translate(x-s, y-s)],
)

View File

@ -1,4 +1,5 @@
import itertools import itertools
from blob import blob
import io import io
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from pathlib import Path from pathlib import Path
@ -66,7 +67,7 @@ class Include(svg.Element):
return self.text return self.text
DEFINED = ".o+tYP-|sSex*" DEFINED = ".o+tYP-|sSex*b"
def markertoSVG(marker, x, y, c, s): def markertoSVG(marker, x, y, c, s):
@ -203,6 +204,8 @@ def markertoSVG(marker, x, y, c, s):
) )
for angle in (0, 60, -60) for angle in (0, 60, -60)
] ]
elif marker == "b":
return blob(x, y, c, np.sqrt(s)*10)
else: else:
return svg.Use( return svg.Use(
href=f"#{marker}", href=f"#{marker}",