amend bug relating to being unable to select on quad tree, related to dividing odd numbers by 2 (because performing integer division on an odd number by 2 results in rounding, which we don't want)
This commit is contained in:
@@ -21,7 +21,7 @@ struct
|
|||||||
val xClickPoints = ClickPoints.generate (wStart, wFinish, canvasWidth)
|
val xClickPoints = ClickPoints.generate (wStart, wFinish, canvasWidth)
|
||||||
val yClickPoints = ClickPoints.generate (hStart, hFinish, canvasHeight)
|
val yClickPoints = ClickPoints.generate (hStart, hFinish, canvasHeight)
|
||||||
|
|
||||||
val maxPoints = Int.max (canvasWidth, canvasHeight) + 1
|
val maxPoints = Int.max (canvasWidth, canvasHeight)
|
||||||
val squares = Vector.tabulate (maxPoints, fn _ =>
|
val squares = Vector.tabulate (maxPoints, fn _ =>
|
||||||
Vector.tabulate (maxPoints, fn _ => 0))
|
Vector.tabulate (maxPoints, fn _ => 0))
|
||||||
in
|
in
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ struct
|
|||||||
, modalNum
|
, modalNum
|
||||||
} = app
|
} = app
|
||||||
|
|
||||||
val maxPoints = Int.max (canvasWidth, canvasHeight) + 1
|
val maxPoints = Int.max (canvasWidth, canvasHeight)
|
||||||
val xClickPoints = ClickPoints.generate (wStart, wFinish, maxPoints)
|
val xClickPoints = ClickPoints.generate (wStart, wFinish, maxPoints)
|
||||||
val yClickPoints = ClickPoints.generate (hStart, hFinish, maxPoints)
|
val yClickPoints = ClickPoints.generate (hStart, hFinish, maxPoints)
|
||||||
in
|
in
|
||||||
|
|||||||
@@ -72,16 +72,20 @@ struct
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
fun toList (tree, acc) =
|
local
|
||||||
case tree of
|
fun loop (tree, acc) =
|
||||||
NODE {x, y, ex, ey, data, left, right} =>
|
case tree of
|
||||||
let
|
NODE {x, y, ex, ey, data, left, right} =>
|
||||||
val acc = toList (right, acc)
|
let
|
||||||
val acc = {x = x, y = y, ex = ex, ey = ey, data = data} :: acc
|
val acc = loop (right, acc)
|
||||||
in
|
val acc = {x = x, y = y, ex = ex, ey = ey, data = data} :: acc
|
||||||
toList (left, acc)
|
in
|
||||||
end
|
loop (left, acc)
|
||||||
| LEAF => acc
|
end
|
||||||
|
| LEAF => acc
|
||||||
|
in
|
||||||
|
fun toList tree = loop (tree, [])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
structure CollisionTree =
|
structure CollisionTree =
|
||||||
@@ -161,7 +165,7 @@ struct
|
|||||||
|
|
||||||
local
|
local
|
||||||
fun loopYAxis (x, y, eX, eY, yAxis, col) =
|
fun loopYAxis (x, y, eX, eY, yAxis, col) =
|
||||||
if y > eY then
|
if y > eY orelse y >= Vector.length yAxis then
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
@@ -172,7 +176,7 @@ struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
fun loopColour (x, y, eX, eY, grid, col) =
|
fun loopColour (x, y, eX, eY, grid, col) =
|
||||||
if x > eX then
|
if x > eX orelse x >= Vector.length grid then
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
@@ -194,23 +198,32 @@ struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
(* tree creation/insertion/query functions *)
|
(* tree creation/insertion/query functions *)
|
||||||
fun build (x, y, size, grid) =
|
fun build (x, y, size, grid, bintree) =
|
||||||
if quadHasSameColour (x, y, x + size, y + size, grid) then
|
if x >= Vector.length grid orelse y >= Vector.length grid then
|
||||||
|
bintree
|
||||||
|
else if quadHasSameColour (x, y, x + size, y + size, grid) then
|
||||||
let
|
let
|
||||||
val yAxis = Vector.sub (grid, x)
|
val yAxis = Vector.sub (grid, x)
|
||||||
val data = Vector.sub (yAxis, y)
|
val data = Vector.sub (yAxis, y)
|
||||||
|
val ex = x + size
|
||||||
|
val ey = y + size
|
||||||
|
val item = {x = x, y = y, ex = ex, ey = ey, data = data}
|
||||||
in
|
in
|
||||||
LEAF {x = x, y = y, ex = x + size, ey = y + size, data = data}
|
BinTree.insert (item, bintree)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val halfSize = size div 2
|
(* handles odd-number divisions.
|
||||||
val tl = build (x, y, halfSize, grid)
|
* For example, `7 div 2` is 3 because of integer division. *)
|
||||||
val tr = build (x + halfSize, y, halfSize, grid)
|
val halfSize =
|
||||||
val bl = build (x, y + halfSize, halfSize, grid)
|
if size = 1 orelse size mod 2 = 0 then size div 2
|
||||||
val br = build (x + halfSize, y + halfSize, halfSize, grid)
|
else (size + 1) div 2
|
||||||
|
|
||||||
|
val bintree = build (x, y, halfSize, grid, bintree)
|
||||||
|
val bintree = build (x + halfSize, y, halfSize, grid, bintree)
|
||||||
|
val bintree = build (x, y + halfSize, halfSize, grid, bintree)
|
||||||
in
|
in
|
||||||
NODE {tl = tl, bl = bl, tr = tr, br = br}
|
build (x + halfSize, y + halfSize, halfSize, grid, bintree)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun foldWithDuplicates (f, tree, acc) =
|
fun foldWithDuplicates (f, tree, acc) =
|
||||||
@@ -225,54 +238,87 @@ struct
|
|||||||
foldWithDuplicates (f, br, acc)
|
foldWithDuplicates (f, br, acc)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun insertItemIntoTree (item, acc) =
|
fun insertItemIntoTree (item, acc) = BinTree.insert (item, acc)
|
||||||
if #data item <> 0 then
|
|
||||||
BinTree.insert (item, acc)
|
|
||||||
else acc
|
|
||||||
|
|
||||||
fun toList qtree =
|
fun toList qtree =
|
||||||
let val tree = foldWithDuplicates (insertItemIntoTree, qtree, BinTree.empty)
|
foldWithDuplicates (fn (item, acc) => item :: acc, qtree, [])
|
||||||
in BinTree.toList (tree, [])
|
|
||||||
end
|
|
||||||
|
|
||||||
local
|
local
|
||||||
fun loop (windowWidth, windowHeight, squares, acc, canvasWidth,
|
fun getClickPoint (clickPoints, pos) =
|
||||||
canvasHeight, xClickPoints, yClickPoints) =
|
let val idx = Int.min (pos, Vector.length clickPoints - 1)
|
||||||
|
in Vector.sub (clickPoints, idx)
|
||||||
|
end
|
||||||
|
|
||||||
|
fun loop
|
||||||
|
( windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, squares
|
||||||
|
, acc
|
||||||
|
, canvasWidth
|
||||||
|
, canvasHeight
|
||||||
|
, xClickPoints
|
||||||
|
, yClickPoints
|
||||||
|
) =
|
||||||
case squares of
|
case squares of
|
||||||
{x, y, ex, ey, data = _} :: tl =>
|
{x, y, ex, ey, data} :: tl =>
|
||||||
let
|
let
|
||||||
val ex = if ex = x then x + 1 else ex
|
val ex = if ex = x then x + 1 else ex
|
||||||
val ey = if ey = y then y + 1 else ey
|
val ey = if ey = y then y + 1 else ey
|
||||||
|
|
||||||
val x = Vector.sub (xClickPoints, x)
|
val x = getClickPoint (xClickPoints, x)
|
||||||
val ex = Vector.sub (xClickPoints, ex)
|
val y = getClickPoint (yClickPoints, y)
|
||||||
val y = Vector.sub (yClickPoints, y)
|
val ex = getClickPoint (xClickPoints, ex)
|
||||||
val ey = Vector.sub (yClickPoints, ey)
|
val ey = getClickPoint (yClickPoints, ey)
|
||||||
|
|
||||||
val startX = Ndc.fromPixelX (x, windowWidth, windowHeight)
|
val startX = Ndc.fromPixelX (x, windowWidth, windowHeight)
|
||||||
val endX = Ndc.fromPixelX (ex , windowWidth, windowHeight)
|
val endX = Ndc.fromPixelX (ex, windowWidth, windowHeight)
|
||||||
val startY = Ndc.fromPixelY (y, windowWidth, windowHeight)
|
val startY = Ndc.fromPixelY (y, windowWidth, windowHeight)
|
||||||
val endY = Ndc.fromPixelY (ey , windowWidth, windowHeight)
|
val endY = Ndc.fromPixelY (ey, windowWidth, windowHeight)
|
||||||
|
|
||||||
val vec =
|
val acc =
|
||||||
Ndc.ltrbToVertexRgb (startX, startY, endX, endY, 0.0, 0.0, 0.0)
|
if data <> 0 then
|
||||||
val acc = vec :: acc
|
Ndc.ltrbToVertexRgb (startX, startY, endX, endY, 0.0, 0.0, 0.0)
|
||||||
|
:: acc
|
||||||
|
else
|
||||||
|
acc
|
||||||
in
|
in
|
||||||
loop (windowWidth, windowHeight, tl, acc, canvasWidth, canvasHeight,
|
loop
|
||||||
xClickPoints, yClickPoints)
|
( windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, tl
|
||||||
|
, acc
|
||||||
|
, canvasWidth
|
||||||
|
, canvasHeight
|
||||||
|
, xClickPoints
|
||||||
|
, yClickPoints
|
||||||
|
)
|
||||||
end
|
end
|
||||||
| [] => Vector.concat acc
|
| [] => Vector.concat acc
|
||||||
in
|
in
|
||||||
fun toTriangles (windowWidth, windowHeight, squares, size, canvasWidth,
|
fun toTriangles
|
||||||
canvasHeight, xClickPoints, yClickPoints) =
|
( windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, squares
|
||||||
|
, size
|
||||||
|
, canvasWidth
|
||||||
|
, canvasHeight
|
||||||
|
, xClickPoints
|
||||||
|
, yClickPoints
|
||||||
|
) =
|
||||||
let
|
let
|
||||||
val qtree = build (0, 0, size, squares)
|
val bintree = build (0, 0, size, squares, BinTree.empty)
|
||||||
val squares = toList qtree
|
val squares = BinTree.toList bintree
|
||||||
val msg = List.length squares
|
|
||||||
val () = print (Int.toString msg ^ "\n")
|
|
||||||
in
|
in
|
||||||
loop (windowWidth, windowHeight, squares, [], canvasWidth, canvasHeight,
|
loop
|
||||||
xClickPoints, yClickPoints)
|
( windowWidth
|
||||||
|
, windowHeight
|
||||||
|
, squares
|
||||||
|
, []
|
||||||
|
, canvasWidth
|
||||||
|
, canvasHeight
|
||||||
|
, xClickPoints
|
||||||
|
, yClickPoints
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user