68 lines
3.6 KiB
Org Mode
68 lines
3.6 KiB
Org Mode
:PROPERTIES:
|
|
:ID: 4f3f07d3-a05e-40ad-94f9-cb35dad69ef1
|
|
:END:
|
|
#+title: Quadtree
|
|
|
|
Recursively subdivide an AABB into 4 regions, hence Quad. They are usually
|
|
denoted as North West, North East, South West, and South East (NW, NE, SW, SE).
|
|
Several things can be created with this;
|
|
* Linked Implementation :datastructure:
|
|
* Array Implementation :datastructure:
|
|
* Insertion :algorithm:
|
|
* Query :algorithm:
|
|
* Find Nearest Neighbor :algorithm:
|
|
* Morton codes
|
|
This is a technique that allows us to convert coordinates into an array index,
|
|
allowing us to pack them contiguously in memory
|
|
http://johnsietsma.com/2019/12/05/morton-order-introduction/
|
|
* Resources
|
|
[[http://ericandrewlewis.github.io/how-a-quadtree-works/][Visualize a Quadtree]]
|
|
[[http://donar.umiacs.umd.edu/quadtree/][Academic Interactive Demo]]
|
|
[[https://codepen.io/_bm/pen/ExPBMrW][Codepen (Js example)]]
|
|
[[https://gist.github.com/patricksurry/6478178][D3.js Example]]
|
|
* Notes
|
|
#+begin_src js
|
|
// exclude node if point is farther away than best distance in either axis
|
|
if (x < x1 - best.d || x > x2 + best.d || y < y1 - best.d || y > y2 + best.d) {
|
|
return best;
|
|
}
|
|
#+end_src
|
|
|
|
|
|
I don't know how to explain but I get it. Because of the euclidian distance and the fact that we're dealing with rectangles, the closest distance to a rectangle is a straight line in one of the x or y axis
|
|
So if the point we're checking is farther away from the rectangle on either axis, then it cannot possible be the case that it is closer
|
|
I still can't visualize or understand it intuitively, I more just trust that it works, maybe if I see it in action it'll click better
|
|
JosephFerano
|
|
—
|
|
Today at 4:15 PM
|
|
This is some clever math shit this guy is doing
|
|
Or that he picked up
|
|
https://gist.github.com/patricksurry/6478178
|
|
Gist
|
|
D3JS quadtree nearest neighbor algorithm
|
|
D3JS quadtree nearest neighbor algorithm. GitHub Gist: instantly share code, notes, and snippets.
|
|
D3JS quadtree nearest neighbor algorithm
|
|
|
|
// check if kid is on the right or left, and top or bottom
|
|
// and then recurse on most likely kids first, so we quickly find a
|
|
// nearby point and then exclude many larger rectangles later
|
|
var kids = node.nodes;
|
|
var rl = (2*x > x1 + x2), bt = (2*y > y1 + y2);
|
|
if (kids[bt*2+rl]) best = nearest(x, y, best, kids[bt*2+rl]);
|
|
if (kids[bt*2+(1-rl)]) best = nearest(x, y, best, kids[bt*2+(1-rl)]);
|
|
if (kids[(1-bt)*2+rl]) best = nearest(x, y, best, kids[(1-bt)*2+rl]);
|
|
if (kids[(1-bt)*2+(1-rl)]) best = nearest(x, y, best, kids[(1-bt)*2+(1-rl)]);
|
|
|
|
That's kinda neat, estimating probability with some math and then going into the index of the array where the point is more likely to be
|
|
No idea why this works
|
|
But I think I'm done with this
|
|
Interesting, he doesn't even check if any of the rects contain the point
|
|
Hmmm
|
|
Oh I see
|
|
It's because he's tracking whether a node is visited or not, and I'm putting in a lot of work to make sure you don't revisit the same node twice, but I don't do it with a "visited" bool, which I intentionally avoided but now seeing his solution, I realize it may have been a mistake
|
|
JosephFerano
|
|
—
|
|
Today at 4:27 PM
|
|
Actually I don't think adding "visited" is a good idea, because you have to walk through the whole thing again once you're done to uncheck all the visited bools. That's a linear walk through all the nodes, which might not be much, but it's certainly making things slower
|
|
I'll have to investigate further
|