module ParasitemiaCore.KdTree
open System
+open System.Collections.Generic
type I2DCoords =
abstract X : float32
buildTreeFromSortedArray xSorted ySorted 1
- member this.Search (searchRegion : Region) : 'a list =
- let rec valuesFrom (tree : Tree<'a>) (acc : 'a list) : 'a list =
+ member this.Search (searchRegion : Region) : List<'a> =
+ let result = List<'a> ()
+ let rec valuesFrom (tree : Tree<'a>) =
match tree with
- | Node (_, left, right) -> (valuesFrom right (valuesFrom left acc))
- | Leaf v -> v :: acc
+ | Node (_, left, right) ->
+ valuesFrom right
+ valuesFrom left
+ | Leaf v ->
+ result.Add v
- let rec searchWithRegion (tree : Tree<'a>) (currentRegion : Region) (depth : int) : 'a list =
+ let rec searchWithRegion (tree : Tree<'a>) (currentRegion : Region) (depth : int) =
match tree with
- | Leaf v -> if searchRegion.Contains v.X v.Y then [v] else []
+ | Leaf v ->
+ if searchRegion.Contains v.X v.Y then
+ result.Add v
| Node (splitValue, part1, part2) ->
- let valuesInRegion (region : Region) (treeRegion : Tree<'a>) =
+ let inline valuesInRegion (region : Region) (treeRegion : Tree<'a>) =
if region.IsSub searchRegion then
- valuesFrom treeRegion []
+ valuesFrom treeRegion
elif region.Intersects searchRegion then
searchWithRegion treeRegion region (depth + 1)
- else
- []
if depth % 2 = 1 then // Vertical splitting.
- let leftRegion = { currentRegion with maxX = splitValue }
- let rightRegion = { currentRegion with minX = splitValue }
- (valuesInRegion leftRegion part1) @ (valuesInRegion rightRegion part2)
+ valuesInRegion { currentRegion with maxX = splitValue } part1 // Left region.
+ valuesInRegion { currentRegion with minX = splitValue } part2 // Right region.
else // Horizontal splitting.
- let downRegion = { currentRegion with maxY = splitValue }
- let upRegion = { currentRegion with minY = splitValue }
- (valuesInRegion downRegion part1) @ (valuesInRegion upRegion part2)
+ valuesInRegion { currentRegion with maxY = splitValue } part1 // Down region.
+ valuesInRegion { currentRegion with minY = splitValue } part2 // Up region.
searchWithRegion this { minX = Single.MinValue; maxX = Single.MaxValue; minY = Single.MinValue; maxY = Single.MaxValue } 1
+ result