에듀테크 프로젝트 대시보드
쿼드트리 (Quadtree)
화면에 점 1,000개가 떠다니고, "마우스 주변 40px 안에 있는 점"을 매 프레임 찾아야 한다고 하자. 모든 점과 거리를 재면 프레임마다 1,000번 검사 — O(n). 쿼드트리는 2차원 공간 자체를 네 개의 사분면으로 계속 쪼개서 트리로 만든다. 한 칸에 점이 일정 개수(용량)를 넘으면 그 칸을 다시 4등분한다. 이렇게 하면 질의 영역과 겹치지 않는 칸은 통째로 건너뛸 수 있어, 평균 O(log n) 근처로 줄어든다. 게임 충돌 검사, 이미지 압축, 지도 데이터, 은하 시뮬레이션(Barnes–Hut)이 모두 같은 아이디어를 쓴다.
# 경계(x, y, w, h)를 가진 사각 영역 노드 class QuadTree: def __init__(self, boundary, capacity=4): self.boundary = boundary # Rect self.capacity = capacity self.points = [] self.divided = False def insert(self, p): if not self.boundary.contains(p): return False # 이 칸 밖 → 무시 if len(self.points) < self.capacity and not self.divided: self.points.append(p) return True if not self.divided: self.subdivide() # 4등분 + 기존 점 재분배 return (self.nw.insert(p) or self.ne.insert(p) or self.sw.insert(p) or self.se.insert(p)) def query(self, range_rect, found): if not self.boundary.intersects(range_rect): return found # ★ 겹침 없음 → 서브트리 통째로 스킵 for p in self.points: if range_rect.contains(p): found.append(p) if self.divided: for child in (self.nw, self.ne, self.sw, self.se): child.query(range_rect, found) return found
| 항목 | 전수 검사 (배열) | 쿼드트리 |
|---|---|---|
| 범위 질의 | O(n) — 모든 점 확인 | 평균 O(log n) + 결과 수 |
| 삽입 | O(1) | 평균 O(log n) |
| 메모리 | 점 배열만 | 노드마다 경계·자식 포인터 추가 |
| 약점 | 점이 많으면 느림 | 점이 한 좌표에 몰리면 무한 분할 → 최대 깊이 제한 필요 |
broad phase 처리