6 ms·
Functional Quadtrees
- Waterluvian 10mo agoI love the visualization, which gave me an idea: what if we numbered every "Looking at" step in the visualization? Then it's obvious just how many search steps it takes. And then maybe even juxtapose that with a linear search example, which also numbers every step. I bet this would make it really click for some people. And for free the user can also play with how a linear search can sometimes be faster when they just want the first element! As a bonus: allow the user to change the cell count so they can really feel just how each method scales!
- OisinMoran 10mo agoNeat! Weirdly sending this article from my phone (Pixel 8) to my browser (Arc) via Pushbullet resulted in an incredibly strange bug that it loads this site instead: https://www.lindelystables.dk/en/posts/functional-quadtree-clojure https://www.lindelystables.dk/en/posts/functional-quadtree-c... Got very confused! I challenge the HN hivemind to figure out what's going on.
- mutkach 10mo agoI remember Arc randomly rewriting my bookmarks using some kind of summarization model or something like that, it also sometimes changed the name of downloaded files reinterpreting their names. Maybe it is related somehow. Well, I guess it was the first AI-first browser, hence all this bs. I uninstalled it months ago...
- OisinMoran 10mo agoYeah that feature was nice at the start then got very annoying. Still like the browser though. Weirdly enough chrome on my phone has been reporting the wrong URLs, usually one I've just been on.
- lbj 10mo agoApologies! I think I might have a found an eager redirect on the server. I haven't been able to reproduce, but you're not the first to report it. I hope it's fixed now.
- wiz21c 10mo agoI think it is weird to have two cells divided downto their smallest size when my cursor clearly occupies only one of them, not two.
- runemadsen 10mo agoWe just did a whole visual identity around the quadtree concept. Take a scroll on this one! https://trace.systems/ https://trace.systems/
- dwb 10mo agoThat all sounds incredibly dystopian, ugh.
- CyberDildonics 10mo agoa whole visual identity around the quadtree concept What does that mean?
- wenc 10mo agoThat is a cool visualization of a quad tree. I use quadtrees in geospatial applications (to partition lat longs) but this is the time I’ve seen it used to render a photo. Quad trees are abstract until you see what they look like. It’s a clever method to partition 2D points. (Kd trees are even better)
- torusle 10mo ago"I could only find a couple tutorials/guides and both were imperative" Aren't Quadtrees covered by almost all basic data-structure books? It is the most simple form of taking the binary tree into the next (2D) dimension.
- pixelpoet 10mo agoYou can even build them with basically one line of code by sorting points using Morton / Z-curve order. It's linear time if you use a counting/radix sort. Edit: lol, downvoted for this post. Never change, HN.
- pavlov 10mo agoIt’s super easy to click the downvote button by accident on mobile when you meant to upvote. And this UI will never be fixed because this is HN after all.
- craftkiller 10mo agoThis is precisely the reason that I do not log in to HN on my phone. My phone is read-only and if I want to upvote or comment then I have to switch to my laptop. Pretty easy with firefox because I can send tabs to other devices.
- jasonjmcghee 10mo agoZoom in or unvote/revote
- acters 10mo agoThat is why I like harmonic app, there is an invite button separating the upvote and downvote. Never going to have this kind of issue
- proc0 10mo agoI just implemented an HN UI. This is good feedback as I'm aiming to have a mobile friendly web version. https://proc0.github.io/HackerZen https://proc0.github.io/HackerZen (it's also open source)
- willvarfar 10mo agoA general quadtree implementation question that puzzled me when I was implementing it myself for hobby games was: do you store a rectangle in the smallest node that completely contains it? Most code that I saw that used quadtrees were treating things as points and storing them only at the lowest level. I also made mine auto-divide by counting items that are entirely in a quadrant as they are added to the node, with allocate and split triggered if a count went above a certain threshold. Anything novel or oopsie?
- CyberDildonics 10mo agoIn 3D this has to be dealt with in the form of polygons and I think it was common when people were using acceleration grids and kd-trees to split the polygons so they fit neatly. That being said most ray tracing seems to do bounding volume hierarchies now, so maybe a bvh is the best way to deal with things that have volume.
- pengaru 10mo agoWhen I made a quadtree for some simple 2d games I handled AABB areas, since it was aimed at broad-phase collision detection of what were essentially sprites just rendered w/GL. Similar to yours I split the leaf nodes when they became too full, with some simple fixed threshold defining "full". Only leaf nodes contained references to the indexed objects, and all overlapping leaf nodes would reference the objects they overlapped. Search queries were done also using an AABB, and would iteratively invoke a callback for all overlapping object AABBs found in the overlapping leaf nodes. IIRC the object references hanging off the leaf nodes had a fixed number of linked list slots to be put on a results list during a search, to deduplicate the results before iterating that list with the provided candidate-found callback. Since any given indexed object could be on many leaf nodes in the index, if they spanned a large area shared with a high density of other indexed objects for instance. It was up to the callback to do the narrow-phase collision detection / control the results list iterating stop vs. continue via return value. I recall one of the annoyances of sticking the search results linked list entry in the object references hanging off the leaf nodes was it set a limit to the number of simultaneous searches one could perform against the index. Basically the game would initialize the index with a fixed maximum concurrent number of searches to handle, and that set the number of results-linked-list slots the object references would be allocated to accommodate. As long as that was never exceeded it worked great. It's been a while so I may have gotten it wrong, but that sounds right to me. Not sure what the most common approaches are... The C source is @ https://git.pengaru.com/cgit/libix2/.git/tree/src/ix2.c https://git.pengaru.com/cgit/libix2/.git/tree/src/ix2.c
- marvinborner 10mo agoQuadtrees are also quite useful for generating fractals. A very related project of mine, Lambda Screen [0], explores this by encoding these functional quadtrees directly in lambda calculus and rendering the structure based on Church booleans being true (white) or false (black). With fixed point recursion, this allows for very tiny definitions of IFS fractals. For example, fractals like the Sierpinski triangle/carpet only require ~50 bit of binary lambda calculus [1] [2]! [0]: https://text.marvinborner.de/2024-03-25-02.html https://text.marvinborner.de/2024-03-25-02.html [1]: https://lambda-screen.marvinborner.de/?term=ERoc0CrYLYA%3D https://lambda-screen.marvinborner.de/?term=ERoc0CrYLYA%3D [2]: https://lambda-screen.marvinborner.de/?term=QcCqqttsFtsI0OaA https://lambda-screen.marvinborner.de/?term=QcCqqttsFtsI0OaA
- senderista 10mo agoI wish the article had made it clearer that quadtree positions are encoded as strings over the alphabet on 2 bits (similarly, octrees use the alphabet over 3 bits). This makes storing keys and lexicographically comparing them very simple.
- almostgotcaught 10mo ago> positions are encoded as strings over the alphabet on 2 bits This is the most pedantic way of saying "binary 2-tuples" I've ever seen. Also for quadtrees this is inferior to base 4 because you can assume clockwise (or counter) ordering.
- mkehrt 10mo agoI don't think that's what they meant. It's the case you can use literal strings of bits to encode a (2^n)-tree node, so you use actual bitstring comparisons and operations to manipulate them. Rightshift gives you the parent and things like that. I don't think this is something the article cares about, though.
- senderista 10mo agoThank you, that is exactly what I meant.
- senderista 10mo agoUh, base 4 is exactly what I meant. I guess I wasn't very clear that I mean positions are encoded as bitstrings, with one pair of bits for each level (and triples of bits for octrees). Is that clear enough for you?
- TacticalCoder 10mo agoNobody praised Clojure yet in this thread: so a little shoot out to Clojure from a clojurist!
- lemonwaterlime 10mo agoI like to do data-oriented programming, and was just thinking about how I want to organize (and search through) the primary data structures/concepts for a project I'm working on. Part of that involved thinking about things like what information I might cache and what representations data might take. That lead me to looking into the nuances of things like B-Trees, AVL Trees, Quadtrees, k-d trees and so forth. I've found the book "Foundations of Multidimensional and Metric Data Structures" by Hanan Samet to be an excellent resource when looking for a slightly deeper dive than a more introductory algorithms course. It goes in depth on the nuances of these approaches, many of which are highly similar at a cursory glance.
- andoando 10mo agoDammit why these books have to be $60
- incognito124 10mo agoJust ask anna if she has it in her archive
- dswalter 10mo agoI see USD $36 on ebay, used. It's a smaller barrier to entry.
- KPGv2 10mo agobecause they have low demand, meaning they would lose money if the price were lower
- deleted 10mo ago[deleted]
- enigma101 10mo agoThe language hurts the eyes
- lbj 10mo agoHow so ?
- catapart 10mo agoI appreciate that this writeup takes care to call out use cases when they help with understanding! I do have a semi-unrelated question though: does using the recursive approach prevent it from being calculated efficiently on the GPU/compute shaders? Not that it matters; plenty of value in a CPU-bound version of a solution and especially one that is easy to understand when recursive. I was just wondering why the prominent examples used a non-recursive approach, but then I was like "oh, because they expect you to use them on the GPU". ...and then I was like "wait, is that why?"
- djmips 10mo agoNon recursive approaches can help on the CPU as well. It's just easy and elegant to do function recusion but not necessarily faster.
- cpgxiii 10mo ago> I do have a semi-unrelated question though: does using the recursive approach prevent it from being calculated efficiently on the GPU/compute shaders? Historically speaking, the use of recursion in shaders and GPGPU kernels (e.g. OpenCL "C" prior to 1.2) was effectively prohibited. The shader/kernel compiler would attempt to inline function calls, since traditional GPU models had little in the way of supporting call stacks like normal CPU programs have, and thus recursion would be simply banned in the shader/kernel language.