amend 'foldRegion' function in MakeQuadFolder functor, by ensuring we don't visit only one child if item has coordinates in more than one child

This commit is contained in:
2025-01-20 10:46:09 +00:00
parent 6783dac9e0
commit 9c46e09ce4

View File

@@ -9,12 +9,50 @@ functor MakeQuadFolder(Fn: QUAD_FOLDER) =
struct struct
open QuadTreeType open QuadTreeType
fun visitTopLeft (iX, iY, iW, iH, qX, qY, qW, qH) =
let
val midX = qW div 2 + qX
val midY = qH div 2 + qY
in
iX <= midX andalso iY <= midY
end
fun visitTopRight (iX, iY, iW, iH, qX, qY, qW, qH) =
let
val midX = qW div 2 + qX
val midY = qH div 2 + qY
in
iX >= midX andalso iY <= midY
end
fun visitBottomLeft (iX, iY, iW, iH, qX, qY, qW, qH) =
let
val midX = qW div 2 + qX
val midY = qH div 2 + qY
val iFinishY = iY + iH
in
iX <= midX andalso iFinishY >= midY
end
fun visitBottomRight (iX, iY, iW, iH, qX, qY, qW, qH) =
let
val midX = qW div 2 + qX
val midY = qH div 2 + qY
val iFinishX = iX + iH
val iFinishY = iY + iH
in
iFinishX >= midX andalso iFinishY >= midY
end
fun foldVec (iX, iY, iW, iH, pos, elements, state, env) = fun foldVec (iX, iY, iW, iH, pos, elements, state, env) =
if pos = Vector.length elements then if pos = Vector.length elements then
state state
else else
let let
val {itemID, ...} = Vector.sub (elements, pos) val {itemID, ...} = Vector.sub (elements, pos)
val _ = print ("foldVec itemID: " ^ Int.toString itemID ^ "\n")
val state = Fn.fState (state, env, itemID) val state = Fn.fState (state, env, itemID)
in in
foldVec (iX, iY, iW, iH, pos + 1, elements, state, env) foldVec (iX, iY, iW, iH, pos + 1, elements, state, env)
@@ -42,68 +80,84 @@ struct
val halfW = quadW div 2 val halfW = quadW div 2
val halfH = quadH div 2 val halfH = quadH div 2
val midX = halfW + quadX
val midY = halfH + quadY
val iX = itemX
val iY = itemY
val iW = itemW
val iH = itemH
val qX = quadX
val qY = quadY
val qW = quadW
val qH = quadH
val vtl = visitTopLeft (iX, iY, iW, iH, qX, qY, qW, qH)
val vtr = visitTopRight (iX, iY, iW, iH, qX, qY, qW, qH)
val vbl = visitBottomLeft (iX, iY, iW, iH, qX, qY, qW, qH)
val vbr = visitBottomRight (iX, iY, iW, iH, qX, qY, qW, qH)
val state =
if vtl then
foldRegion
(iX, iY, iW, iH, qX, qY, halfW, halfH, env, state, topLeft)
else
state
val state =
if vtr then
foldRegion
( itemX
, itemY
, itemW
, itemH
, midX
, quadY
, halfW
, halfH
, env
, state
, topRight
)
else
state
val state =
if vbl then
foldRegion
( itemX
, itemY
, itemW
, itemH
, quadX
, midY
, halfW
, halfH
, env
, state
, bottomLeft
)
else
state
in in
(case if vbr then
QuadTree.whichQuadrant foldRegion
(itemX, itemY, itemW, itemH, quadX, quadY, quadW, quadH) ( itemX
of , itemY
TOP_LEFT => , itemW
foldRegion , itemH
( itemX , midX
, itemY , midY
, itemW , halfW
, itemH , halfH
, quadX , env
, quadY , state
, halfW , bottomRight
, halfH )
, env else
, state state
, topLeft
)
| TOP_RIGHT =>
foldRegion
( itemX
, itemY
, itemW
, itemH
, quadX + halfW (* middleX *)
, quadY
, halfW
, halfH
, env
, state
, topRight
)
| BOTTOM_LEFT =>
foldRegion
( itemX
, itemY
, itemW
, itemH
, quadX
, quadY + halfH (* middleY *)
, halfW
, halfH
, env
, state
, bottomLeft
)
| BOTTOM_RIGHT =>
foldRegion
( itemX
, itemY
, itemW
, itemH
, quadX + halfW (* middleX *)
, quadY + halfH (* middleY *)
, halfW
, halfH
, env
, state
, bottomRight
)
| PARENT_QUADRANT => state)
end end
| LEAF elements => | LEAF elements =>
foldVec (itemX, itemY, itemW, itemH, 0, elements, state, env) foldVec (itemX, itemY, itemW, itemH, 0, elements, state, env)