Shape Helpers
Shape helpers return SVG path d strings. Use them with Path
or with data-driven generators.
These helpers are exported from top-level pydreamplet.
import pydreamplet as dp
Visual Example
import pydreamplet as dp
svg = dp.SVG(420, 190)
svg.append(
dp.Path(dp.star(58, 58, n=5, inner_radius=18, outer_radius=40, angle=-90), fill="currentColor"),
dp.Path(dp.superellipse(155, 58, rx=48, ry=34, exponent=4, n=48), fill="currentColor", opacity=0.68),
dp.Path(dp.rounded_polygon([(245, 22), (320, 36), (306, 106), (232, 100)], radius=14), fill="none", stroke="currentColor", stroke_width=4),
dp.Path(dp.blob(372, 64, radius=38, variance=0.22, n=10, seed=5), fill="currentColor", opacity=0.35),
dp.Path(dp.ring(96, 142, inner_radius=20, outer_radius=42, start_angle=-35, end_angle=250), fill="currentColor", opacity=0.45),
dp.Path(dp.cross(210, 142, size=74, thickness=22, angle=35), fill="none", stroke="currentColor", stroke_width=4),
)
Point Input
Curve and polygon helpers that accept points use PointInput:
type PointInput = Sequence[float] | Sequence[Sequence[float]]
Both forms are valid:
dp.linear_path([0, 0, 10, 20, 30, 0])
dp.linear_path([(0, 0), (10, 20), (30, 0)])
Flat point lists must contain an even number of values. Point-pair items must contain exactly two coordinates.
Basic Shapes
star(
x: float = 0,
y: float = 0,
n: int = 5,
*,
inner_radius: float,
outer_radius: float,
angle: float = 0,
) -> str
Creates an alternating inner/outer star. n must be at least 2.
inner_radius must be non-negative and outer_radius must be positive.
polygon(x: float, y: float, radius: float, n: int, angle: float = 0) -> str
Creates a regular polygon centered at (x, y). n must be at least 3.
radius must be non-negative.
cross(
x: float = 0,
y: float = 0,
*,
size: float,
thickness: float,
angle: float = 0,
) -> str
Creates a 12-point cross. size and thickness must be positive.
thickness must be less than or equal to size.
superellipse(
x: float = 0,
y: float = 0,
*,
rx: float,
ry: float,
exponent: float = 4,
n: int = 64,
angle: float = 0,
) -> str
Creates a closed superellipse. exponent=2 is ellipse-like. Larger values
create squarer sides. rx, ry, and exponent must be positive. n must be
at least 4.
Organic and Rounded Shapes
rounded_polygon(points: PointInput, *, radius: float) -> str
Creates a closed polygon with quadratic rounded corners. It requires at least
three points. radius=0 falls back to linear_path(points, closed=True).
blob(
x: float = 0,
y: float = 0,
*,
radius: float,
variance: float = 0.25,
n: int = 12,
seed: int = 0,
smooth: bool = True,
) -> str
Creates a deterministic organic closed shape. smooth=True uses a closed
Catmull-Rom path. smooth=False uses straight segments.
Line and Curve Paths
polyline(x_coords: Sequence[float], y_coords: Sequence[float]) -> str
Creates an open line path from separate x and y sequences. Both sequences must have the same non-zero length.
linear_path(points: PointInput, closed: bool = False) -> str
Creates straight line segments. Empty input returns an empty string.
step_path(
points: PointInput,
closed: bool = False,
mode: Literal["before", "after", "mid"] = "mid",
) -> str
Creates stepped segments. mode="before" changes y before x, mode="after"
changes x before y, and mode="mid" changes y at the midpoint between adjacent
x values.
cardinal_spline(points: PointInput, tension: float = 0.0, closed: bool = False) -> str
catmull_rom_path(points: PointInput, closed: bool = False) -> str
basis_spline(points: PointInput, closed: bool = False) -> str
monotone_x_path(points: PointInput) -> str
monotone_y_path(points: PointInput) -> str
Spline helpers return cubic Bezier path data. Closed Catmull-Rom, basis, and
cardinal paths require at least three points. cardinal_spline() requires
0 <= tension <= 1.
monotone_x_path() requires strictly monotonic x coordinates.
monotone_y_path() requires strictly monotonic y coordinates.
Arcs and Rings
arc(
x: float = 0,
y: float = 0,
*,
radius: float,
start_angle: float = 0,
end_angle: float = 360,
) -> str
Creates a circular arc. A zero span returns a move-only path. A full circle is
drawn as two 180-degree arc commands. radius must be positive.
ring(
x: float = 0,
y: float = 0,
*,
inner_radius: float,
outer_radius: float,
start_angle: float = 0,
end_angle: float = 360,
without_inner: bool = False,
) -> str
Creates a donut or ring segment. A zero span returns an empty string.
inner_radius must be non-negative, outer_radius must be positive, and
inner_radius <= outer_radius.
For partial rings, without_inner=True omits the inner arc and leaves the path
open.
Example Output
import pydreamplet as dp
assert dp.linear_path([(0, 0), (10, 20), (30, 0)]) == (
"M 0.00,0.00 L 10.00,20.00 L 30.00,0.00"
)
assert dp.ring(inner_radius=5, outer_radius=10, start_angle=30, end_angle=30) == ""