diff --git a/dotscape b/dotscape index a40e2fc..2334bc4 100755 Binary files a/dotscape and b/dotscape differ diff --git a/fcore/quad-tree.sml b/fcore/quad-tree.sml index 7f0fa41..5a7db3c 100644 --- a/fcore/quad-tree.sml +++ b/fcore/quad-tree.sml @@ -93,7 +93,8 @@ struct end | LEAF => acc - fun toList tree = foldr (fn (item, acc) => item ::acc, tree, []) + fun toList tree = + foldr (fn (item, acc) => item :: acc, tree, []) end structure CollisionTree = @@ -189,10 +190,10 @@ struct ) end) - fun getClickPoint (clickPoints, pos) = - let val idx = Int.min (pos, Vector.length clickPoints - 1) - in Vector.sub (clickPoints, idx) - end + fun getClickPoint (clickPoints, pos) = + let val idx = Int.min (pos, Vector.length clickPoints - 1) + in Vector.sub (clickPoints, idx) + end fun folder ( windowWidth @@ -313,58 +314,134 @@ struct NODE {tl = tl, tr = tr, bl = bl, br = br} end) - local - fun loop (x, y, ex, ey, grid) = - if x > 0 then - if quadHasSameColour (x, y, ex, ey, grid) then - loop (x - 1, y, x, ey, grid) - else - ex + local + fun loop (x, y, ex, ey, grid) = + if x > 0 then + if quadHasSameColour (x, y, ex, ey, grid) then + loop (x - 1, y, x, ey, grid) else - 0 - in - fun getLeftmostX ({x, y, ex, ey, data}, grid) = - loop (x - 1, y, x, ey, grid) - end + ex + else + 0 + in + fun getLeftmostX ({x, y, ex, ey, data}, grid) = + loop (x - 1, y, x, ey, grid) + end - local - fun loop (x, y, ex, ey, grid) = - if x < Vector.length grid andalso ex < Vector.length grid then - if quadHasSameColour (x, y, ex, ey, grid) then - loop (ex, y, ex + 1, ey, grid) - else - x + local + fun loop (x, y, ex, ey, grid) = + if x < Vector.length grid andalso ex < Vector.length grid then + if quadHasSameColour (x, y, ex, ey, grid) then + loop (ex, y, ex + 1, ey, grid) else - Vector.length grid - 1 - in - fun getRightmostX ({x, y, ex, ey, data}, grid) = - loop (ex, y, ex + 1, ey, grid) - end + x + else + Vector.length grid - 1 + in + fun getRightmostX ({x, y, ex, ey, data}, grid) = + loop (ex, y, ex + 1, ey, grid) + end - local - fun loop (x, y, ex, ey, grid) = - if y < 0 then 0 - else - if quadHasSameColour (x, y, ex, ey, grid) then - loop (x, y - 1, ex, y, grid) - else - ey - in - fun getTopmostY ({x, y, ex, ey, data}, grid) = + local + fun loop (x, y, ex, ey, grid) = + if y < 0 then + 0 + else if quadHasSameColour (x, y, ex, ey, grid) then loop (x, y - 1, ex, y, grid) - end + else + ey + in + fun getTopmostY ({x, y, ex, ey, data}, grid) = + loop (x, y - 1, ex, y, grid) + end - local - fun loop (x, y, ex, ey, grid) = - if y < Vector.length grid andalso ey < Vector.length grid then - if quadHasSameColour (x, y, ex, ey, grid) then - loop (x, ey, ex, ey + 1, grid) - else - y + local + fun loop (x, y, ex, ey, grid) = + if y < Vector.length grid andalso ey < Vector.length grid then + if quadHasSameColour (x, y, ex, ey, grid) then + loop (x, ey, ex, ey + 1, grid) else - Vector.length grid - 1 + y + else + Vector.length grid - 1 + in + fun getBottomY ({x, y, ex, ey, data}, grid) = + loop (x, ey, ex, ey + 1, grid) + end + + local + fun loop (tree, grid) = + case tree of + EMPTY => (EMPTY, false) + | LEAF (oldItem as {x, y, ex, ey, data}) => + let + val topY = getTopmostY (oldItem, grid) + val bottomY = getBottomY (oldItem, grid) + val newItem = {y = topY, ey = bottomY, x = x, ex = ex, data = data} + val didItemChange = newItem <> oldItem + in + (LEAF newItem, didItemChange) + end + | NODE {tl, tr, bl, br} => + let + val (tl, didTlChange) = loop (tl, grid) + val (tr, didTrChange) = loop (tr, grid) + val (bl, didBlChange) = loop (bl, grid) + val (br, didBrChange) = loop (br, grid) + + val node = NODE {tl = tl, tr = tr, bl = bl, br = br} + val didChange = + didTlChange orelse didTrChange orelse didBlChange + orelse didBrChange + in + (node, didChange) + end + in + fun mergeVertical (tree, grid) = + let val (newTree, didChange) = loop (tree, grid) + in if didChange then mergeVertical (newTree, grid) else newTree + end + end + + local + fun loop (tree, grid) = + case tree of + EMPTY => (EMPTY, false) + | LEAF (oldItem as {x, y, ex, ey, data}) => + let + val leftX = getLeftmostX (oldItem, grid) + val rightX = getRightmostX (oldItem, grid) + val newItem = {x = leftX, ex = rightX, y = y, ey = ey, data = data} + val didItemChange = newItem <> oldItem + in + (LEAF newItem, didItemChange) + end + | NODE {tl, tr, bl, br} => + let + val (tl, didTlChange) = loop (tl, grid) + val (tr, didTrChange) = loop (tr, grid) + val (bl, didBlChange) = loop (bl, grid) + val (br, didBrChange) = loop (br, grid) + + val node = NODE {tl = tl, tr = tr, bl = bl, br = br} + val didChange = + didTlChange orelse didTrChange orelse didBlChange + orelse didBrChange + in + (node, didChange) + end + in + fun mergeHorizontal (tree, grid) = + let val (newTree, didChange) = loop (tree, grid) + in if didChange then mergeHorizontal (newTree, grid) else newTree + end + end + + fun merge (tree, grid) = + let + val tree = mergeVertical (tree, grid) + val tree = mergeHorizontal (tree, grid) in - fun getBottomY ({x, y, ex, ey, data}, grid) = - loop (x, ey, ex, ey + 1, grid) + BinTree.toList tree end end