done implementing pointer quad tree (next: benchmark the two)

This commit is contained in:
2025-02-01 09:54:35 +00:00
parent 28380957b3
commit bf3f0b3927
3 changed files with 148 additions and 4 deletions

View File

@@ -0,0 +1,92 @@
signature POINTER_QUAD_FOLDER =
sig
type env
type state
val fold: int * env * state -> state
end
signature MAKE_POINTER_QUAD_TREE_FOLD =
sig
structure Fn: POINTER_QUAD_FOLDER
val foldRegion: int * int * int * int *
Fn.env * Fn.state * {tree: PointerQuadTreeType.t, width: int, height: int}
-> Fn.state
end
functor MakePointerQuadTreeFold(Fn: POINTER_QUAD_FOLDER): MAKE_POINTER_QUAD_TREE_FOLD =
struct
structure Fn = Fn
open PointerQuadTreeType
fun foldRegionList (rx, ry, rw, rh, env, state, lst) =
case lst of
item :: tl =>
let
val state =
if isCollidingItem (rx, ry, rw, rh, ~1, item) then
Fn.fold (#itemID item, env, state)
else
state
in
foldRegionList (rx, ry, rw, rh, env, state, tl)
end
| [] => state
fun helpFoldRegion (rx, ry, rw, rh, env, state, qx, qy, qw, qh, tree) =
case tree of
NODE {tl, tr, bl, br} =>
let
val vtl = visitTopLeft (rx, ry, rw, rh, qx, qy, qw, qh)
val vtr = visitTopRight (rx, ry, rw, rh, qx, qy, qw, qh)
val vbl = visitBottomLeft (rx, ry, rw, rh, qx, qy, qw, qh)
val vbr = visitBottomRight (rx, ry, rw, rh, qx, qy, qw, qh)
val hw = qw div 2
val hh = qh div 2
val state =
if vtl then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx, qy, hw, hh, tl)
else
state
val state =
if vtr then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx + hw, qy, hw, hh, tr)
else
state
val state =
if vbl then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx, qy + hh, hw, hh, bl)
else
state
in
if vbr then
helpFoldRegion
(rx, ry, rw, rh, env, state, qw + hw, qy + hh, hw, hh, br)
else
state
end
| LEAF item =>
if isCollidingItem (rx, ry, rw, rh, ~1, item) then
Fn.fold (#itemID item, env, state)
else
state
| EMPTY => state
| SHARE_LEAF items => foldRegionList (rx, ry, rw, rh, env, state, items)
fun foldRegion (rx, ry, rw, rh, env, state, tree) =
let
val {width, height, tree} = tree
in
helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
end
end

View File

@@ -1,4 +1,19 @@
structure PointerQuadTree = signature POINTER_QUAD_TREE =
sig
type t
val insert: int * int * int * int * int * t -> t
val getCollisions: int * int * int * int * int * t -> int list
val hasCollisionAt: int * int * int * int * int * t -> bool
val getItemID: int * int * int * int * t -> int
val create: int * int -> t
end
structure PointerQuadTree: POINTER_QUAD_TREE =
struct struct
open PointerQuadTreeType open PointerQuadTreeType
@@ -195,4 +210,40 @@ struct
let val newItem = mkItem (itemID, ix, iy, iw, ih) let val newItem = mkItem (itemID, ix, iy, iw, ih)
in splitShareLeaf (qx, qy, qw, qh, oldItems, newItem) in splitShareLeaf (qx, qy, qw, qh, oldItems, newItem)
end end
fun insert (iX, iY, iW, iH, itemID, tree: t) =
let
val {width, height, tree} = tree
val tree =
helpInsert (iX, iY, iW, iH, itemID, 0, 0, width, height, tree)
in
{width = width, height = height, tree = tree}
end
structure GetCollisions = MakePointerQuadTreeFold (struct
type env = unit
type state = int list
fun fold (itemID, (), lst) = itemID :: lst
end)
fun getCollisions (itemX, itemY, itemWidth, itemHeight, _, tree) =
GetCollisions.foldRegion (itemX, itemY, itemWidth, itemHeight, (), [], tree)
structure HasCollisionAt = MakePointerQuadTreeFold (struct
type env = unit
type state = bool
fun fold _ = true
end)
fun hasCollisionAt (ix, iy, iw, ih, _, tree) =
HasCollisionAt.foldRegion (ix, iy, iw, ih, (), false, tree)
structure GetItemID = MakePointerQuadTreeFold (struct
type env = unit
type state = int
fun fold (itemID, (), curID) = Int.max (itemID, curID)
end)
fun getItemID (ix, iy, iw, ih, tree) =
GetItemID.foldRegion (ix, iy, iw, ih, (), ~1, tree)
end end

View File

@@ -7,6 +7,10 @@ fcore/quad-tree-type.sml
fcore/quad-tree-fold.sml fcore/quad-tree-fold.sml
fcore/quad-tree.sml fcore/quad-tree.sml
fcore/pointer-quad-tree-type.sml
fcore/pointer-quad-tree-fold.sml
fcore/pointer-quad-tree.sml
fcore/bin-search.sml fcore/bin-search.sml
fcore/bin-vec.sml fcore/bin-vec.sml
@@ -39,9 +43,6 @@ fcore/projectile.sml
fcore/player-enemy.sml fcore/player-enemy.sml
fcore/game-update.sml fcore/game-update.sml
fcore/pointer-quad-tree-type.sml
fcore/pointer-quad-tree.sml
(* shell *) (* shell *)
$(SML_LIB)/basis/mlton.mlb $(SML_LIB)/basis/mlton.mlb