2025-08-09 07:48:49 +01:00
|
|
|
structure LayerTree =
|
|
|
|
|
struct
|
|
|
|
|
datatype tree =
|
2025-08-09 08:43:51 +01:00
|
|
|
NODE of {key: int, value: Grid.t, left: tree, right: tree}
|
2025-08-09 07:48:49 +01:00
|
|
|
| LEAF
|
|
|
|
|
|
2025-08-09 08:15:11 +01:00
|
|
|
val emptyTree = LEAF
|
|
|
|
|
|
2025-08-09 07:48:49 +01:00
|
|
|
fun insert (newKey, newValue, tree) =
|
|
|
|
|
case tree of
|
|
|
|
|
LEAF => NODE {key = newKey, value = newValue, left = LEAF, right = LEAF}
|
|
|
|
|
| NODE {key, value, left, right} =>
|
|
|
|
|
if newKey < key then
|
|
|
|
|
let val left = insert (newKey, newValue, left)
|
|
|
|
|
in NODE {key = key, value = value, left = left, right = right}
|
|
|
|
|
end
|
|
|
|
|
else if newKey > key then
|
|
|
|
|
let val right = insert (newKey, newValue, right)
|
|
|
|
|
in NODE {key = key, value = value, left = left, right = right}
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
NODE {key = key, value = newValue, left = left, right = right}
|
|
|
|
|
|
|
|
|
|
fun get (searchKey, tree) =
|
|
|
|
|
case tree of
|
|
|
|
|
LEAF => NONE
|
|
|
|
|
| NODE {key, value, left, right} =>
|
|
|
|
|
if searchKey < key then get (searchKey, left)
|
|
|
|
|
else if searchKey > key then get (searchKey, right)
|
|
|
|
|
else SOME value
|
|
|
|
|
|
2025-08-09 08:04:22 +01:00
|
|
|
fun foldl (f, tree, acc) =
|
|
|
|
|
case tree of
|
|
|
|
|
LEAF => acc
|
|
|
|
|
| NODE {value, left, right, ...} =>
|
|
|
|
|
let
|
|
|
|
|
val acc = foldl (f, left, acc)
|
|
|
|
|
val acc = f (value, acc)
|
|
|
|
|
in
|
|
|
|
|
foldl (f, right, acc)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun map (f, tree) =
|
|
|
|
|
case tree of
|
|
|
|
|
LEAF => LEAF
|
|
|
|
|
| NODE {key, value, left, right} =>
|
|
|
|
|
let
|
|
|
|
|
val left = map (f, left)
|
|
|
|
|
val right = map (f, right)
|
|
|
|
|
val newValue = f value
|
|
|
|
|
in
|
|
|
|
|
NODE {key = key, value = value, left = left, right = right}
|
|
|
|
|
end
|
|
|
|
|
|
2025-08-09 07:48:49 +01:00
|
|
|
(* copies non-blank pixels in value vector into acc *)
|
|
|
|
|
fun helpFlatten (value, acc) =
|
|
|
|
|
Vector.mapi
|
|
|
|
|
(fn (xIdx, valueYAxis) =>
|
|
|
|
|
Vector.mapi
|
|
|
|
|
(fn (yIdx, valuePixel) =>
|
2025-08-09 08:43:51 +01:00
|
|
|
if Grid.isBlank valuePixel then
|
2025-08-09 07:48:49 +01:00
|
|
|
let val accYAxis = Vector.sub (acc, xIdx)
|
|
|
|
|
in Vector.sub (accYAxis, yIdx)
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
valuePixel) valueYAxis) value
|
|
|
|
|
|
2025-08-09 08:04:22 +01:00
|
|
|
fun makeEmptyGrid maxSide =
|
|
|
|
|
Vector.tabulate (maxSide, fn _ =>
|
2025-08-09 08:43:51 +01:00
|
|
|
Vector.tabulate (maxSide, fn _ => Grid.emptyPixel))
|
2025-08-09 08:04:22 +01:00
|
|
|
|
|
|
|
|
fun flatten (maxSide, tree) =
|
|
|
|
|
foldl (helpFlatten, tree, makeEmptyGrid maxSide)
|
|
|
|
|
|
|
|
|
|
fun changeGridSize (maxSide, tree) =
|
2025-08-09 08:43:51 +01:00
|
|
|
let val f = Grid.changeGridSize maxSide
|
2025-08-09 08:04:22 +01:00
|
|
|
in map (f, tree)
|
|
|
|
|
end
|
2025-08-09 07:48:49 +01:00
|
|
|
end
|