Skip to content

Commit 4e4bafc

Browse files
committed
content(blog): quadtree
1 parent 233a279 commit 4e4bafc

File tree

2 files changed

+131
-2
lines changed

2 files changed

+131
-2
lines changed

public/posts/posts.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
[
2+
{
3+
"slug": "quadtree-algorithm-spatial-indexing",
4+
"title": "The Quadtree: Solving the O(N^2) Spatial Nightmare",
5+
"date": "2026-02-21",
6+
"updated": "2026-02-21",
7+
"description": "A deep dive into spatial partitioning with Quadtrees, explaining how to avoid O(N^2) nightmares with recursive decomposition.",
8+
"tags": [
9+
"algorithms",
10+
"spatial-indexing",
11+
"quadtree",
12+
"dev",
13+
"math",
14+
"optimization"
15+
],
16+
"category": "dev",
17+
"filename": "quadtree-algorithm-spatial-indexing.txt",
18+
"authors": [
19+
"fezcode"
20+
]
21+
},
222
{
323
"slug": "gobake-go-build-orchestrator",
424
"title": "gobake: The Build Orchestrator Go Was Missing",
@@ -15,7 +35,9 @@
1535
],
1636
"category": "dev",
1737
"filename": "gobake-go-build-orchestrator.txt",
18-
"authors": ["fezcode"]
38+
"authors": [
39+
"fezcode"
40+
]
1941
},
2042
{
2143
"slug": "tag-file-systems-explained-go-implementation",
@@ -2103,4 +2125,4 @@
21032125
"fezcode"
21042126
]
21052127
}
2106-
]
2128+
]
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
> This analysis was built by a Software Engineer who once tried to simulate 10,000 particles and watched his CPU melt into a puddle of $O(N^2)$ regret.
2+
> If the recursion depth makes your head spin, just imagine you're looking at a very organized square pizza.
3+
4+
## Divide and Conquer the Map: A Deep Dive into Quadtrees
5+
6+
In game development and spatial computing, the "Proximity Problem" is the ultimate boss.
7+
If you have $N$ objects and you want to know which ones are colliding, the naive approach is to check every object against every other object.
8+
9+
As software engineers, we know that $O(N^2)$ is the "Abandon All Hope" complexity class.
10+
At 100 objects, it's 10,000 checks. At 10,000 objects, it's 100,000,000 checks per frame. Your 144Hz monitor just became a 1 frame-per-hour slideshow.
11+
12+
To solve this, we don't just need a faster loop; we need a smarter structure. Enter the **Quadtree**.
13+
14+
## Part 1: The Engineering Foundation
15+
16+
A Quadtree is a tree data structure in which each internal node has exactly four children. It is the spatial equivalent of a Binary Search Tree, but instead of dividing a 1D line, it divides a 2D plane.
17+
18+
### The Branching Factor: A Comparison
19+
20+
| Tree Type | Dimension | Children per Node | Use Case |
21+
| :--- | :--- | :--- | :--- |
22+
| **Binary Tree** | 1D | 2 | Sorting, Searching (Values) |
23+
| **Quadtree** | 2D | 4 | Collision Detection, Image Compression |
24+
| **Octree** | 3D | 8 | 3D Physics, Voxel Engines, Ray Tracing |
25+
26+
The Quadtree works on a simple principle: **If two objects are in different parts of the world, they cannot possibly be colliding.**
27+
28+
## Part 2: The Architecture of Space
29+
30+
The Quadtree decomposes space recursively. We start with a single bounding box (the "Root"). If that box contains more than a certain number of objects (the "Capacity"), we split it into four equal quadrants: **North-West (NW)**, **North-East (NE)**, **South-West (SW)**, and **South-East (SE)**.
31+
32+
### The Recursive Decomposition
33+
34+
```mermaid
35+
graph TD
36+
Root[Root: Full Map] --> NW[North-West]
37+
Root --> NE[North-East]
38+
Root --> SW[South-West]
39+
Root --> SE[South-East]
40+
41+
NW --> NW_NW[NW-NW]
42+
NW --> NW_NE[NW-NE]
43+
NW --> NW_SW[NW-SW]
44+
NW --> NW_SE[NW-SE]
45+
```
46+
47+
This structure allows us to discard massive chunks of the map instantly. If a player is in the `SE` quadrant, we don't even look at objects in `NW`, `NE`, or `SW`.
48+
49+
## Part 3: Implementation (The Rule of Three)
50+
51+
A robust Quadtree implementation relies on three core components:
52+
53+
1. **Boundary**: A simple rectangle (x, y, width, height) defining the space.
54+
2. **Capacity**: The maximum number of points a node can hold before it MUST split.
55+
3. **Points**: The actual data (x, y coordinates and metadata) being stored.
56+
57+
### The Algorithm Flow
58+
59+
| Step | Action | Logic |
60+
| :--- | :--- | :--- |
61+
| **1. Insert** | Add a point | Check if point is within Boundary. If not, return false. |
62+
| **2. Check Capacity** | Room available? | If points < Capacity, add to list. Return true. |
63+
| **3. Subdivide** | Split! | If points == Capacity, create 4 children. Move current points to children? (Depends on implementation). |
64+
| **4. Query** | Find neighbors | Define a "Search Range". Only check nodes that intersect with this range. |
65+
66+
### The "Query" Optimization
67+
68+
The real magic happens during the `query`. Instead of checking all $N$ points, the Quadtree traverses the tree. If a node's boundary doesn't intersect with your search range, you prune the entire branch.
69+
70+
## Part 4: The Deductions (The Performance Verdict)
71+
72+
By shifting from $O(N^2)$ to $O(N \log N)$ or even $O(\log N)$ for localized queries, the Quadtree transforms the impossible into the trivial.
73+
74+
### Question A: Quadtree vs. Simple Grid?
75+
76+
**The Data Verdict:** Choose the **Quadtree** for **Sparse** environments and the **Grid** for **Uniform** environments.
77+
78+
- **The Reasoning:**
79+
- A **Simple Grid** (dividing the map into $10 \times 10$ squares) is great if players are spread out evenly. But if 100 players crowd into a single square, that square becomes a $O(N^2)$ bottleneck.
80+
- A **Quadtree** is adaptive. It will only subdivide where the action is. If the map is empty, the tree is shallow. If there's a mosh pit in the corner, the tree grows deep *only in that corner*.
81+
- **Deduction:** Quadtrees are "Demand-Driven" structures.
82+
83+
### Question B: What is the optimal "Capacity"?
84+
85+
**The Data Verdict:** **4 to 8 points** is usually the "Goldilocks" zone.
86+
87+
- **The Trade-off:**
88+
- **Capacity = 1**: The tree becomes incredibly deep. You spend more time navigating the tree (memory overhead) than checking collisions.
89+
- **Capacity = 100**: You're basically back to $O(N^2)$ within each node.
90+
- **The Strategy:** Set it high enough to handle small clusters without splitting, but low enough to keep the final intersection checks fast.
91+
92+
### Question C: The "Dynamic" Problem
93+
94+
**The Data Verdict:** Moving objects require **Re-insertion** or **Refitting**.
95+
96+
- **The Challenge:** Quadtrees are easy when points are static (like trees in a forest). When objects move (like bullets), you have two choices:
97+
1. **Clear and Rebuild**: Delete the whole tree and rebuild it every frame. (Surprisingly fast for $N < 5000$).
98+
2. **Update**: Move a point, check if it left its boundary, and "bubble it up" to the parent until it finds a new home.
99+
- **Conclusion:** If your objects are fast and numerous, rebuilding the tree is often more cache-friendly than complex pointer updates.
100+
101+
## Conclusion
102+
103+
The Quadtree is a masterclass in **Spatial Hashing**. It teaches us that the best way to handle a massive problem isn't to work harder, but to categorize the problem until it becomes many tiny, manageable problems.
104+
105+
Whether you're building a 2D bullet hell, a map of the stars, or an image compression algorithm (where quadrants of the same color are merged), the Quadtree is your most reliable spatial ally.
106+
107+
You can check a visual implementation of this in my **Knowledge Graph** or any of my generative art projects that rely on particle proximity!

0 commit comments

Comments
 (0)