use an immutable vector (always of length 4) for representing quad tree's internal nodes
This commit is contained in:
@@ -38,14 +38,17 @@ struct
|
|||||||
|
|
||||||
fun foldRegion (rx, ry, rw, rh, env, state, tree) =
|
fun foldRegion (rx, ry, rw, rh, env, state, tree) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (rx, ry, rw, rh, x, y, w, h) then
|
if isCollidingPlus (rx, ry, rw, rh, x, y, w, h) then
|
||||||
let
|
let
|
||||||
val state = foldRegion (rx, ry, rw, rh, env, state, topLeft)
|
val state =
|
||||||
val state = foldRegion (rx, ry, rw, rh, env, state, topRight)
|
foldRegion (rx, ry, rw, rh, env, state, Vector.sub (nodes, tlIdx))
|
||||||
val state = foldRegion (rx, ry, rw, rh, env, state, bottomLeft)
|
val state =
|
||||||
|
foldRegion (rx, ry, rw, rh, env, state, Vector.sub (nodes, trIdx))
|
||||||
|
val state =
|
||||||
|
foldRegion (rx, ry, rw, rh, env, state, Vector.sub (nodes, blIdx))
|
||||||
in
|
in
|
||||||
foldRegion (rx, ry, rw, rh, env, state, bottomRight)
|
foldRegion (rx, ry, rw, rh, env, state, Vector.sub (nodes, brIdx))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
state
|
state
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ sig
|
|||||||
|
|
||||||
datatype t =
|
datatype t =
|
||||||
NODE of
|
NODE of
|
||||||
{ topLeft: t
|
{ nodes: t vector
|
||||||
, topRight: t
|
|
||||||
, bottomLeft: t
|
|
||||||
, bottomRight: t
|
|
||||||
, x: int
|
, x: int
|
||||||
, y: int
|
, y: int
|
||||||
, w: int
|
, w: int
|
||||||
@@ -15,6 +12,11 @@ sig
|
|||||||
}
|
}
|
||||||
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
||||||
|
|
||||||
|
val tlIdx: int
|
||||||
|
val trIdx: int
|
||||||
|
val blIdx: int
|
||||||
|
val brIdx: int
|
||||||
|
|
||||||
val isColliding: int * int * int * int *
|
val isColliding: int * int * int * int *
|
||||||
int * int * int * int
|
int * int * int * int
|
||||||
-> bool
|
-> bool
|
||||||
@@ -50,10 +52,7 @@ struct
|
|||||||
|
|
||||||
datatype t =
|
datatype t =
|
||||||
NODE of
|
NODE of
|
||||||
{ topLeft: t
|
{ nodes: t vector
|
||||||
, topRight: t
|
|
||||||
, bottomLeft: t
|
|
||||||
, bottomRight: t
|
|
||||||
, x: int
|
, x: int
|
||||||
, y: int
|
, y: int
|
||||||
, w: int
|
, w: int
|
||||||
@@ -61,6 +60,11 @@ struct
|
|||||||
}
|
}
|
||||||
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
||||||
|
|
||||||
|
val tlIdx = 0
|
||||||
|
val trIdx = 1
|
||||||
|
val blIdx = 2
|
||||||
|
val brIdx = 3
|
||||||
|
|
||||||
fun isColliding (ix, iy, ifx, ify, cx, cy, cfx, cfy) =
|
fun isColliding (ix, iy, ifx, ify, cx, cy, cfx, cfy) =
|
||||||
ix < cfx andalso ifx > cx andalso iy < cfy andalso ify > cy
|
ix < cfx andalso ifx > cx andalso iy < cfy andalso ify > cy
|
||||||
|
|
||||||
|
|||||||
@@ -97,10 +97,7 @@ struct
|
|||||||
val br = mkBottomRight (x, y, w, h, br)
|
val br = mkBottomRight (x, y, w, h, br)
|
||||||
in
|
in
|
||||||
NODE
|
NODE
|
||||||
{ topLeft = tl
|
{ nodes = Vector.fromList [tl, tr, bl, br]
|
||||||
, topRight = tr
|
|
||||||
, bottomLeft = bl
|
|
||||||
, bottomRight = br
|
|
||||||
, x = x
|
, x = x
|
||||||
, y = y
|
, y = y
|
||||||
, w = w
|
, w = w
|
||||||
@@ -130,22 +127,19 @@ struct
|
|||||||
|
|
||||||
fun insert (iX, iY, iW, iH, itemID, tree: t) =
|
fun insert (iX, iY, iW, iH, itemID, tree: t) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
||||||
let
|
let
|
||||||
(* we are not necessarily inserting into all nodes.
|
(* we are not necessarily inserting into all nodes.
|
||||||
* If isCollidingPlus returns false recursively,
|
* If isCollidingPlus returns false recursively,
|
||||||
* we return the same node back. *)
|
* we return the same node back. *)
|
||||||
val tl = insert (iX, iY, iW, iH, itemID, topLeft)
|
val tl = insert (iX, iY, iW, iH, itemID, Vector.sub (nodes, tlIdx))
|
||||||
val tr = insert (iX, iY, iW, iH, itemID, topRight)
|
val tr = insert (iX, iY, iW, iH, itemID, Vector.sub (nodes, trIdx))
|
||||||
val bl = insert (iX, iY, iW, iH, itemID, bottomLeft)
|
val bl = insert (iX, iY, iW, iH, itemID, Vector.sub (nodes, blIdx))
|
||||||
val br = insert (iX, iY, iW, iH, itemID, bottomRight)
|
val br = insert (iX, iY, iW, iH, itemID, Vector.sub (nodes, brIdx))
|
||||||
in
|
in
|
||||||
NODE
|
NODE
|
||||||
{ topLeft = tl
|
{ nodes = Vector.fromList [tl, tr, bl, br]
|
||||||
, topRight = tr
|
|
||||||
, bottomLeft = bl
|
|
||||||
, bottomRight = br
|
|
||||||
, x = x
|
, x = x
|
||||||
, y = y
|
, y = y
|
||||||
, w = w
|
, w = w
|
||||||
@@ -206,16 +200,19 @@ struct
|
|||||||
|
|
||||||
fun getCollisionsAll (iX, iY, iW, iH, itemID, acc, tree) =
|
fun getCollisionsAll (iX, iY, iW, iH, itemID, acc, tree) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
||||||
let
|
let
|
||||||
val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, topLeft)
|
val acc =
|
||||||
|
getCollisionsAll (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, tlIdx))
|
||||||
|
|
||||||
val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, topRight)
|
val acc =
|
||||||
|
getCollisionsAll (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, trIdx))
|
||||||
|
|
||||||
val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, bottomLeft)
|
val acc =
|
||||||
|
getCollisionsAll (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, blIdx))
|
||||||
in
|
in
|
||||||
getCollisionsAll (iX, iY, iW, iH, itemID, acc, bottomRight)
|
getCollisionsAll (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, brIdx))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
acc
|
acc
|
||||||
@@ -227,17 +224,20 @@ struct
|
|||||||
|
|
||||||
fun helpGetCollisions (iX, iY, iW, iH, itemID, acc, tree: t) =
|
fun helpGetCollisions (iX, iY, iW, iH, itemID, acc, tree: t) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
||||||
let
|
let
|
||||||
val acc = helpGetCollisions (iX, iY, iW, iH, itemID, acc, topLeft)
|
val acc =
|
||||||
|
helpGetCollisions (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, tlIdx))
|
||||||
|
|
||||||
val acc = helpGetCollisions (iX, iY, iW, iH, itemID, acc, topRight)
|
val acc =
|
||||||
|
helpGetCollisions (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, trIdx))
|
||||||
|
|
||||||
val acc = helpGetCollisions
|
val acc =
|
||||||
(iX, iY, iW, iH, itemID, acc, bottomLeft)
|
helpGetCollisions (iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, blIdx))
|
||||||
in
|
in
|
||||||
helpGetCollisions (iX, iY, iW, iH, itemID, acc, bottomRight)
|
helpGetCollisions
|
||||||
|
(iX, iY, iW, iH, itemID, acc, Vector.sub (nodes, brIdx))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
acc
|
acc
|
||||||
@@ -263,12 +263,12 @@ struct
|
|||||||
|
|
||||||
fun hasCollisionAt (iX, iY, iW, iH, itemID, tree) =
|
fun hasCollisionAt (iX, iY, iW, iH, itemID, tree) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
||||||
hasCollisionAt (iX, iY, iW, iH, itemID, topLeft)
|
hasCollisionAt (iX, iY, iW, iH, itemID, Vector.sub (nodes, tlIdx))
|
||||||
orelse hasCollisionAt (iX, iY, iW, iH, itemID, topRight)
|
orelse hasCollisionAt (iX, iY, iW, iH, itemID, Vector.sub (nodes, trIdx))
|
||||||
orelse hasCollisionAt (iX, iY, iW, iH, itemID, bottomLeft)
|
orelse hasCollisionAt (iX, iY, iW, iH, itemID, Vector.sub (nodes, blIdx))
|
||||||
orelse hasCollisionAt (iX, iY, iW, iH, itemID, bottomRight)
|
orelse hasCollisionAt (iX, iY, iW, iH, itemID, Vector.sub (nodes, brIdx))
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
| LEAF {items, x, y, w, h} =>
|
| LEAF {items, x, y, w, h} =>
|
||||||
@@ -290,13 +290,13 @@ struct
|
|||||||
|
|
||||||
fun getItemID (iX, iY, iW, iH, tree) =
|
fun getItemID (iX, iY, iW, iH, tree) =
|
||||||
case tree of
|
case tree of
|
||||||
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
|
NODE {nodes, x, y, w, h} =>
|
||||||
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
|
||||||
let
|
let
|
||||||
val try1 = getItemID (iX, iY, iW, iH, topLeft)
|
val try1 = getItemID (iX, iY, iW, iH, Vector.sub (nodes, tlIdx))
|
||||||
val try2 = getItemID (iX, iY, iW, iH, topRight)
|
val try2 = getItemID (iX, iY, iW, iH, Vector.sub (nodes, trIdx))
|
||||||
val try3 = getItemID (iX, iY, iW, iH, bottomLeft)
|
val try3 = getItemID (iX, iY, iW, iH, Vector.sub (nodes, blIdx))
|
||||||
val try4 = getItemID (iX, iY, iW, iH, bottomRight)
|
val try4 = getItemID (iX, iY, iW, iH, Vector.sub (nodes, brIdx))
|
||||||
|
|
||||||
(* get max: we assume query was narrow enough
|
(* get max: we assume query was narrow enough
|
||||||
* that only one ID is valid *)
|
* that only one ID is valid *)
|
||||||
|
|||||||
Reference in New Issue
Block a user