fractals.barnsley_fern¶
The Barnsley fern is a fractal that resembles the black spleenwort fern. It was described by the British mathematician Michael Barnsley in his 1988 book Fractals Everywhere and is a classic example of an iterated function system (IFS).
An IFS builds a fractal by repeatedly applying a small set of affine
transformations, each chosen at random with a fixed probability. Starting from
the point (0, 0) the fern uses four transformations:
Transformation |
Effect |
Probability |
|---|---|---|
Stem |
collapse onto the y-axis |
1% |
Successive leaf |
the main self-similar copy of the fern |
85% |
Left leaflet |
a smaller rotated/reflected copy |
7% |
Right leaflet |
another smaller rotated/reflected copy |
7% |
Because the whole picture is produced by chance the doctests below seed Python’s random generator so that the results are reproducible. Plotting the points with matplotlib is optional and only happens when the module is run directly.
Reference: https://en.wikipedia.org/wiki/Barnsley_fern
Attributes¶
Functions¶
|
Map a value |
|
Generate |
|
Apply the affine transformation |
Module Contents¶
- fractals.barnsley_fern.choose_transformation(sample: float) int¶
Map a value
samplefrom[0, 1)to a transformation index using the cumulative probabilities of the fern.>>> choose_transformation(0.0) 0 >>> choose_transformation(0.5) 1 >>> choose_transformation(0.9) 2 >>> choose_transformation(0.97) 3
- fractals.barnsley_fern.generate_fern(iterations: int, seed: int | None = None) list[tuple[float, float]]¶
Generate
iterationspoints of the Barnsley fern, starting at(0, 0).Passing a
seedmakes the (otherwise random) output reproducible, which is what keeps the doctests deterministic.>>> points = generate_fern(5, seed=0) >>> len(points) 5 >>> points[0] (0.0, 0.0) >>> points [(0.0, 0.0), (0.0, 1.6), (0.064, 2.96), (0.1728, 4.11344), (0.3114176, 5.089512)]
Every fern point lives inside the well known bounding box.
>>> cloud = generate_fern(2000, seed=42) >>> all(-2.182 <= x <= 2.6558 for x, _ in cloud) True >>> all(0.0 <= y <= 9.9984 for _, y in cloud) True >>> generate_fern(0) Traceback (most recent call last): ... ValueError: iterations must be positive, got 0
- fractals.barnsley_fern.transform(point: tuple[float, float], index: int) tuple[float, float]¶
Apply the affine transformation
indextopointand return the image.>>> transform((0.0, 0.0), 0) (0.0, 0.0) >>> transform((1.0, 1.0), 1) (0.89, 2.41) >>> transform((2.0, 3.0), 3) (0.54, 1.68) >>> transform((0.0, 0.0), 4) Traceback (most recent call last): ... IndexError: index must be in range 0..3, got 4
- fractals.barnsley_fern.CUMULATIVE_PROBABILITIES: tuple[float, ...] = (0.01, 0.86, 0.93, 1.0)¶
- fractals.barnsley_fern.TRANSFORMATIONS: tuple[tuple[float, float, float, float, float, float], ...]¶
- fractals.barnsley_fern.fern_points¶