#spacefillingcurve

2025-05-19

Testing the Gosper curve in my variable iteration halftoning setup. So far I've only used the Hilbert curve this way, and things get a bit coarser with the Gosper, so it was harder to find images that make nice results. So here we are with the old Venus again.

The number of points multiplies by 4 for Hilbert and 7 for Gosper on each step, so the latter has to get by with fewer iterations for a sensible resolution. Here we have 6 iterations for 6 grey levels.

#halftoneart #gospercurve #planefillingcurve #spacefillingcurve #singlelinedrawing #pythoncode #opengl #algorithmicart #algorist #mathart #laskutaide #ittaide #kuavataide #iterati

2025-05-15

In the last post, Tis Veugen suggested dithering with the Gosper curve. At first I thought this doesn't make sense, since the curve lives on a hexagonal lattice, while dithering is generally done at the native pixel level, which means a square lattice. But as I thought about this further, it started to look like a fun challenge. Besides, the square grid hasn't always been the native way to organize pixels; for example, some old CRTs also used a hex lattice.

So I was really just making up excuses for the extra work. First I had to set up interpolated sampling, which would come for free in OpenGL, but now I was working on the CPU. The Gosper curve was also new to me, and I implemented it in my own way from first principles using IFS ideas, like I'd done earlier with the Peano curve.

For comparison, here's also a version with the boustrophedon curve on a hexagon, since I already had that curve function in my toolbox. Finally there's also the raw Gosper curve, though a smaller version to give a clearer idea.

#dithering #halftoneart #raster #pixelart #gospercurve #planefillingcurve #spacefillingcurve #pythoncode #opengl #algorithmicart #algorist #mathart #laskutaide #ittaide #kuavataide #iterati

2025-05-10

The previous demo made me dig deeper into dithering algorithms. It's something I should have done years ago, as I've been using simple random dithering now and then, and I hadn't even thought of gamma correction. One algorithm in particular caught my eye: Riemersma dithering, which uses the Hilbert curve. Compared to the usual matrices for error diffusion, the curve approach seemed easier to implement in some ways, as it has fewer edge issues.

More interestingly, it struck a chord with my earlier experiments with space-filling curves in image processing. So it was a kind of familiar territory, but it also seemed esoteric enough that I could imagine making some new discoveries. For example, play with other plane-filling curves besides the Hilbert.

The first image uses the boustrophedon curve, which makes the vertical wave patterns I recall from a number of non-dithering demos. The second curve is what I call the diagstrophedon, a diagonal zig-zag starting from the top left corner, and I think its wavy artefacts make a nice match for Venus's hair.

Then in image 3 we have Hilbert, which doesn't seem to make any particular artefacts, and I guess that's a good thing for dithering. Finally 4 uses the Peano curve, which makes some fun wiggles in light areas.

#dithering #riemersmadithering #stippling #halftoneart #raster #pixelart #hilbertcurve #peanocurve #planefillingcurve #spacefillingcurve #pythoncode #opengl #algorithmicart #algorist #mathart #laskutaide #ittaide #kuavataide #iterati

2025-04-27

How it was supposed to look like in the first place: rounded with Bezier curves.

I've used Bezier curves and Hermite splines quite a lot to smooth out progressions of discrete points, such as Hamiltonian circuits. The challenge with this Hilbert curve is that there are tens of thousands of points, so drawing a nice OpenGL shape for each edge gets rather slow. Of course, this isn't a deal breaker for still images, but I like making my code efficient.

I've now constructed the Bezier curves in geometry shaders. I've used those for some time to draw simpler shapes more efficiently, such as line segments with rounded ends; the idea is to do more work on the GPU, while moving as little data as possible there. These line segments only need the endpoint coordinates, as well as thickness and colour. The curves seemed more challenging due to the number of parameters, but in the end there weren't really any issues.

#beziercurve #hilbertcurve #planefillingcurve #spacefillingcurve #lineart #linedrawing #singlelinedrawing #pythoncode #opengl #geometryshader #algorithmicart #algorist #mathart #laskutaide #ittaide #kuavataide #iterati

2025-04-26

The recent stipplings and partitionings reminded me of this demo from about 2 years ago. In short, it's a Hilbert curve where the iteration level varies by the colour value. I wanted to make some small changes, but I ended up rewriting it completely. The shader approach seemed needlessly heavy and redundant for something that works more naturally on a CPU. But mostly it was just a fun exercise in looking at the same problem from a different angle.

The first picture shows the original idea. With the new idea, I wanted to get rid of the slanted lines; the result doesn't feel any better to me, but I guess it's interesting in its own way.

#hilbertcurve #planefillingcurve #spacefillingcurve #lineart #linedrawing #singlelinedrawing #pythoncode #opengl #algorithmicart #algorist #mathart #laskutaide #ittaide #kuavataide #iterati

Dan Drake 🦆ddrake@mathstodon.xyz
2023-07-08

Postal codes are basically space-filling curves, if you think about it.

Interesting article on the design behind the US's ZIP codes:

newspapers.com/image/207561765

(And yes, it's "ZIP", not "zip" -- it's an acronym. Bonus magic internet points to anyone who knows what the acronym means without looking it up...)

#math #postalcodes #spacefillingcurve #geometry

A clipping from a newspaper from 1963 when the United States starting using ZIP codes for mail.

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst