I got started with algorithmic art because I wanted to push my Python skills further. Online tutorials are fine, but I learn best when there is a real goal to work toward. Something creative and a little open-ended.
A lot of inspiration came from Tyler Hobbs… his long-form generative work, his articles and talks. If you have not read his writing on flow fields, go do that.
Over time the exploration became a series. Each project named after a person. Each one a different experiment. Zara is the latest. And in all honesty, I am not a huge fan of the final result.
That is worth saying clearly rather than quietly moving past it.
What Zara Was Going For
The goal was concrete texture. That raw, tactile feel of stone. Not to replicate it perfectly — more to distill the essence into layers that a program could build up.
I broke it down into five elements:
- Base colour layer — a foundation that captures the natural hues of stone
- Noise texture — randomness to mimic inherent irregularities
- Crack patterns — gentle wear of time on concrete
- Grunge and scratches — imperfection, life
- Final noise overlay — a unifying pass to blend everything together
Sequential building blocks. Each layer contributing something specific before the next one arrives.
The Tools
I wanted to produce a static image that could scale to any size. That shaped the library choices:
- Pillow — standard image manipulation
- aggdraw — high-performance anti-aliased drawing
- svgpathtools — scalable vector paths
- noise — specifically
pnoise2for Perlin noise - SciPy.ndimage — Gaussian blur and edge detection for the final blend
- NumPy, colorsys, math — the usual supporting cast
Also NeoVim for coding, Git for versioning, venv for keeping dependencies contained. The standard workflow by this point.
How the Code Runs
The main function acts as conductor. Each layer arrives in sequence:
- Canvas creation — blank slate with a base colour
- Colour band generation — a reference image to sample from
- Base grain drawing — first set of grains laid down
- Blemish generation — subtle marks via Perlin noise
- Perlin-based patch generation — shaped patches with texture
- Block array and crack lines — brick-like structure with fractures
- Final blending — Gaussian blur and noise overlay to merge the layers
- Save and display
Each function is an orchestra member. Main keeps everything in tune.
One thing I embraced properly with Zara: type hints and docstrings throughout. Tools like mypy catch type mismatches before they become bugs. And when I come back to this code in six months, the docstrings will save me a lot of painful re-reading. Small discipline, high return.
On Not Loving the Result
Some of my projects produce that wow feeling… surprise at what came out.
Zara was not one of those.
But that does not make it a failure. If anything it is one of the more honest entries in the series. Not everything that teaches you something looks impressive when it is done. Zara taught me about layering, about Perlin noise as a texture tool, about structured randomness and when it does and does not produce the feeling you are after.
The best surprises in generative art happen when you loosen your grip on controlling every aspect and let the algorithms have a seat at the creative table. Zara reminded me of that. Even when the outcome is not what you hoped for, the process was still real.
For anyone curious about generative art: embrace the iterative process. Push boundaries. Mix libraries. Experiment with parameters that seem unconventional. That is where the code and the art meet in ways you did not expect.
If you have not read the Yasmin post, that one covers the yarn algorithm — a project where the result did produce that wow feeling. Worth reading alongside this one.
Full code for Zara on GitHub at @galiquis.



