berlin.social is one of the many independent Mastodon servers you can use to participate in the fediverse.
Alles rund um, über, aus & für Berlin

Administered by:

Server stats:

681
active users

And the source code to the function above…

@jack lovely! here's my JS port of your code...

@jack that's such a lovely pattern 🖤

@neauoire And useful for so many things! :)

@jack What could I use it for? The only reason I ever had to use it in kind of practical application was for raycasting, is there other practical purposes for it?

@neauoire They can used wherever a quadtree can be used, for one example. This makes them good for geospatial applications (they’re used inside Google maps, or at least were). In image processing they’re useful for dithering, compression, and I’ve gotten good results training image models on an HC representation rather than a grid. In short, anywhere that maintaining coherence between neighbouring pixels is beneficial.

@jack Brings back faint memories of trying to use it for image compression—followed by a calculating differences between pixels that are adjacent on the curve—to benefit from locality. Didn’t get any mind blowing results, but it was good fun.

@jack May I ask what you're using to draw it? I've been looking for a simple drawing lib to play around with for Clojure for a while

@jack thanks mate! Can't believe I've never come across that lol

@derpapa69 I look forward to seeing what you draw with it 😊

@jack I haven't forgotten this 🙂

Where's this algorithm from? Closest I could find to it was dl.acm.org/doi/10.1145/290200.

@neauoire @qualmist

@akkartik @neauoire @qualmist From? I improvised it while live coding 🤷🏻‍♂️

@jack 🤯 I need to think about why this algorithm is the same as the L-system based version in Wikipedia.

(Who needs eso-langs, computing is plenty esoteric to begin with.)

@akkartik @jack Two alternative versions that may aid your understanding... #1 chooses what I think are better variable names, since the xs & ys are mixed up in the original version. #2 uses vector operations. It would look a lot better with overloaded operators... but it's helpful anyway to see that the program is really operating on the vector level.

@qualmist Ahh, the first version in particular helps a lot! I still don't understand why it works, but at least I have more of an intuition now of what the variables are.

@jack

@akkartik @jack Cool! I can also use some human words and say: (x, y) is the top-left of the curve's square, (x1, y1) is a vector from the top-left to the bottom-left, and (x2, y2) is a vector from the top-left to the top-right. So you're taking a big square and sub-dividing it into smaller squares, in a particular order & with particular orientations.

@qualmist That does help. Do top/bottom/left/right rotate through the recursive calls?

@jack

@akkartik @jack yeah, they gotta for the ends of the curves to join up!

@qualmist @akkartik This implementation was hacked together while making this logo. The complete source for which is here:

github.com/nextjournal/clerk-d

They are absolutely vector operations, but I was trying to make things brief without adding a dep on a vector lib. I couldn’t avoid vector multiply though. 😆

> (hilbert-curve 0 0 800 0 0 800 5)

@jack It's interesting that I get back jank if I replace the (... n 0 0 n ...) pattern with other possibilities.

Does the hilbert curve logo thing you made with curved lines start out from this version?

@qualmist

@jack Visualizing leaf calls. x, y in red, xi/yi/xj/yj in green.

@qualmist

@jack I better handle when the debug information collides.

@qualmist

@jack Even better, show which direction the base vs control points are used in.

@qualmist