X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemiaCore%2FKdTree.fs;fp=Parasitemia%2FParasitemiaCore%2FKdTree.fs;h=3a51aac919bbf82fe83480bcccdbc94fd3b98439;hp=2525e272cdeca45051975e2ce2d20474794e2a07;hb=31078fdde95f1b239110dfe29998e9b03e3a9bea;hpb=ef07574f9326af515348bfbd8a0cf606ec337c3a diff --git a/Parasitemia/ParasitemiaCore/KdTree.fs b/Parasitemia/ParasitemiaCore/KdTree.fs index 2525e27..3a51aac 100644 --- a/Parasitemia/ParasitemiaCore/KdTree.fs +++ b/Parasitemia/ParasitemiaCore/KdTree.fs @@ -1,6 +1,7 @@ module ParasitemiaCore.KdTree open System +open System.Collections.Generic type I2DCoords = abstract X : float32 @@ -62,31 +63,34 @@ type Tree<'a when 'a :> I2DCoords> = 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