Advertisement
Guest User

jockey

a guest
Jan 30th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.67 KB | None | 0 0
  1. import Array (..)
  2. import Text (asText)
  3. import Graphics.Collage (..)
  4. import Color (..)
  5.  
  6. drawBox box =
  7. move (box.horizontal.low + boxHalfWidth box, box.vertical.low + boxHalfHeight box) <|
  8. outlined (solid black) <|
  9. rect (boxWidth box) (boxHeight box)
  10.  
  11.  
  12. drawQuadTree quadTree =
  13. case quadTree of
  14. Leaf box items -> [drawBox box]
  15. Node box quadTreeNE quadTreeNW quadTreeSW quadTreeSE ->
  16. drawQuadTree quadTreeNE ++
  17. drawQuadTree quadTreeNW ++
  18. drawQuadTree quadTreeSW ++
  19. drawQuadTree quadTreeSE
  20.  
  21. box lowX highX lowY highY = {
  22. horizontal = {
  23. low = lowX,
  24. high = highX },
  25. vertical = {
  26. low = lowY,
  27. high = highY }}
  28.  
  29. testBox = box -200 200 -200 200
  30.  
  31. item1 = box 10 20 10 20
  32. item2 = box 30 40 0 50
  33. item3 = box -100 -80 80 100
  34. item4 = box 40 50 -40 0
  35. item5 = box -50 -40 70 80
  36. item6 = box -100 -80 130 190
  37. item7 = box -20 -10 20 100
  38.  
  39.  
  40.  
  41. testQuadTree =
  42. emptyQuadTree testBox |>
  43. insertQuadTree item1 |>
  44. insertQuadTree item2 |>
  45. insertQuadTree item3 |>
  46. insertQuadTree item4 |>
  47. insertQuadTree item5 |>
  48. insertQuadTree item6 |>
  49. insertQuadTree item7
  50.  
  51. renderQuadTree quadTree = collage 400 400 (drawQuadTree quadTree)
  52.  
  53. main = renderQuadTree testQuadTree
  54.  
  55.  
  56. ---------
  57.  
  58. dropIf : (a -> Bool) -> Array a -> Array a
  59. dropIf predicate = filter (not << predicate)
  60.  
  61. ---------
  62.  
  63.  
  64. type alias Interval = {
  65. low : Float,
  66. high : Float
  67. }
  68.  
  69. type alias Box = {
  70. horizontal : Interval,
  71. vertical : Interval
  72. }
  73.  
  74. type QuadTree a =
  75. Leaf Box (Array a) |
  76. Node Box (QuadTree a) (QuadTree a) (QuadTree a) (QuadTree a)
  77.  
  78. emptyQuadTree : Box -> QuadTree a
  79. emptyQuadTree box = Leaf box empty
  80.  
  81. lengthQuadTree : QuadTree a -> Int
  82. lengthQuadTree quadTree =
  83. case quadTree of
  84. Leaf box items -> length items
  85. Node box quadTreeNE quadTreeNW quadTreeSW quadTreeSE ->
  86. lengthQuadTree quadTreeNE +
  87. lengthQuadTree quadTreeNW +
  88. lengthQuadTree quadTreeSW +
  89. lengthQuadTree quadTreeSE
  90.  
  91. insertQuadTree : Box -> QuadTree Box -> QuadTree Box
  92. insertQuadTree item quadTree =
  93. case quadTree of
  94. Leaf box items ->
  95. if intersectBoxes item box then
  96. let allItems = push item items
  97. insertNew quadrant =
  98. foldr (\item quadTree -> insertQuadTree item quadTree)
  99. (emptyQuadTree quadrant)
  100. allItems
  101. quadTreeNE = subdivideNE box
  102. quadTreeNW = subdivideNW box
  103. quadTreeSW = subdivideSW box
  104. quadTreeSE = subdivideSE box
  105. in
  106. if length items < 2 then Leaf box (push item items)
  107. else
  108. Node box (insertNew quadTreeNE)
  109. (insertNew quadTreeNW)
  110. (insertNew quadTreeSW)
  111. (insertNew quadTreeSE)
  112. else
  113. quadTree
  114.  
  115. Node box quadTreeNE quadTreeNW quadTreeSW quadTreeSE ->
  116. if intersectBoxes item box then
  117. Node box (insertQuadTree item quadTreeNE)
  118. (insertQuadTree item quadTreeNW)
  119. (insertQuadTree item quadTreeSW)
  120. (insertQuadTree item quadTreeSE)
  121. else
  122. quadTree
  123.  
  124. removeFromQuadTree : a -> QuadTree a -> QuadTree a
  125. removeFromQuadTree item quadTree =
  126. case quadTree of
  127. Leaf box items -> Leaf box (dropIf (\it -> it == item) items)
  128. Node box quadTreeNE quadTreeNW quadTreeSW quadTreeSE ->
  129. Node box (removeFromQuadTree item quadTreeNE)
  130. (removeFromQuadTree item quadTreeNW)
  131. (removeFromQuadTree item quadTreeSW)
  132. (removeFromQuadTree item quadTreeSE)
  133.  
  134.  
  135. boxWidth : Box -> Float
  136. boxWidth box =
  137. box.horizontal.high - box.horizontal.low
  138.  
  139. boxHeight : Box -> Float
  140. boxHeight box =
  141. box.vertical.high - box.vertical.low
  142.  
  143. boxHalfWidth : Box -> Float
  144. boxHalfWidth box =
  145. boxWidth box / 2
  146.  
  147. boxHalfHeight : Box -> Float
  148. boxHalfHeight box =
  149. boxHeight box / 2
  150.  
  151.  
  152. pointInInterval : Float -> Interval -> Bool
  153. pointInInterval point interval =
  154. point < interval.high && point > interval.low
  155.  
  156. intersectIntervals : Interval -> Interval -> Bool
  157. intersectIntervals interval1 interval2 =
  158. pointInInterval interval1.low interval2
  159.  
  160. intersectBoxes : Box -> Box -> Bool
  161. intersectBoxes box1 box2 =
  162. intersectIntervals box1.horizontal box2.horizontal &&
  163. intersectIntervals box1.vertical box2.vertical
  164.  
  165. subdivideNE : Box -> Box
  166. subdivideNE box =
  167. let vlow = box.vertical.low + boxHalfHeight box
  168. hlow = box.horizontal.high - boxHalfWidth box
  169. in {
  170. horizontal = {
  171. low = hlow,
  172. high = box.horizontal.high
  173. },
  174. vertical = {
  175. low = vlow,
  176. high = box.vertical.high
  177. }
  178. }
  179.  
  180. subdivideNW : Box -> Box
  181. subdivideNW box =
  182. let vlow = box.vertical.low + boxHalfHeight box
  183. hhigh = box.horizontal.high - boxHalfWidth box
  184. in {
  185. horizontal = {
  186. low = box.horizontal.low,
  187. high = hhigh
  188. },
  189. vertical = {
  190. low = vlow,
  191. high = box.vertical.high
  192. }
  193. }
  194.  
  195. subdivideSW : Box -> Box
  196. subdivideSW box =
  197. let vhigh = box.vertical.high - boxHalfHeight box
  198. hhigh = box.horizontal.high - boxHalfWidth box
  199. in {
  200. horizontal = {
  201. low = box.horizontal.low,
  202. high = hhigh
  203. },
  204. vertical = {
  205. low = box.vertical.low,
  206. high = vhigh
  207. }
  208. }
  209.  
  210. subdivideSE : Box -> Box
  211. subdivideSE box =
  212. let vhigh = box.vertical.high - boxHalfHeight box
  213. hlow = box.horizontal.low + boxHalfWidth box
  214. in {
  215. horizontal = {
  216. low = hlow,
  217. high = box.horizontal.high
  218. },
  219. vertical = {
  220. low = box.vertical.low,
  221. high = vhigh
  222. }
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement