-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.coffee
62 lines (54 loc) · 1.74 KB
/
index.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# A quad tree is defined as a subdividing 2d plane
# A single tile splits into four, each tile then spits into another four, etc, etc.
# z = the subdivision level
# x, y = the coordinates of the tile in the level
# len = the number of tiles along one edge at a certain z level
# zmax is the maximum z level
module.exports =
# Calculate the coordinates of the tile above
up: (x, y, z) ->
halfx = Math.floor x / 2
halfy = Math.floor y / 2
prevz = z - 1
[halfx, halfy, prevz]
# Calculate the four coodinates of the tiles below
# In order: NW, NE, SE, SW
down: (x, y, z) ->
doublex = x * 2
doubley = y * 2
nextz = z + 1
[
[doublex, doubley, nextz]
[doublex + 1, doubley, nextz]
[doublex + 1, doubley + 1, nextz]
[doublex, doubley + 1, nextz]
]
# Create a preallocated tree, good for random access
preallocate: (zmax) ->
# create the tree structure
levels = [0..zmax].map (z) ->
len = Math.pow 2, z
new Array len * len
# Read a location from the quadtree, may be undefined
get: (x, y, z) ->
len = Math.pow 2, z
return null if z > zmax
return null if y * len + x >= levels[z].length
levels[z][y * len + x]
# Read if available or create if not available
assert: (x, y, z) ->
len = Math.pow 2, z
return null if z > zmax
return null if y * len + x >= levels[z].length
if !levels[z][y * len + x]?
levels[z][y * len + x] = {}
levels[z][y * len + x]
# Visit every node from zstart to zend
visit: (zstart, zend, f) ->
for z in [zstart..zend]
widths = [0...Math.pow(2, z)]
for y in widths
for x in widths
f x, y, z
null
# TODO: Proper lined quadtree?