{- | Module : Data.Octree.BoundingBox.Internal Copyright : Copyright (c) 2016 Michael Litchard License : BSD3 Maintainer : Michael Litchard Stability : experimental Portability: not portable This module provides functions etc, for Data.Octree.BoundingBox.BoundingBox -- | DefInput, LeafValue a, DefOutput a, DefNodeValue a Default types for BBoxConfig -- | filterNodes, points, result Default functions for BBoxConfig -- | inclusive boolean check for one BBox3 being inclusive of another -} module Data.Octree.BoundingBox.Internal ( filterNodes , points , result , DefInput , LeafValue , DefOutput , DefNodeValue , newBBox3 , inclusive ) where import Data.BoundingBox.B3 (BBox3 (..), bound_corners, within_bounds, isect) import Data.Octree.Internal (Vector3 (..), ODir (..)) import Data.List (foldl') type DefInput = Vector3 type Split = Vector3 type LeafValue a = (Vector3, a) type DefOutput = (BBox3, [LeafValue DefNodeValue ]) type DefNodeValue = Int -- | newBBox3 creates a smaller BBox3 -- Given Node name, previous BBox3, and the split newBBox3 :: BBox3 -> Split -> ODir -> BBox3 newBBox3 bbx split' SWD = bound_corners swdCorner neuCorner where swdCorner = Vector3 (minX bbx) (minY bbx) (minZ bbx) neuCorner = Vector3 (v3x split') (v3y split') (v3z split') newBBox3 bbx split' SED = bound_corners swdCorner neuCorner where swdCorner = Vector3 (v3x split') (minY bbx) (minZ bbx) neuCorner = Vector3 (maxX bbx) (v3y split') (v3z split') newBBox3 bbx split' NWD = bound_corners swdCorner neuCorner where swdCorner = Vector3 (minX bbx) (v3y split') (minZ bbx) neuCorner = Vector3 (v3x split') (maxY bbx) (v3z split') newBBox3 bbx split' NED = bound_corners swdCorner neuCorner where swdCorner = Vector3 (v3x split') (v3y split') (minZ bbx) neuCorner = Vector3 (maxX bbx) (maxY bbx) (v3z split') newBBox3 bbx split' SWU = bound_corners swdCorner neuCorner where swdCorner = Vector3 (minX bbx) (minY bbx) (v3z split') neuCorner = Vector3 (v3x split') (v3y split') (maxZ bbx) newBBox3 bbx split' SEU = bound_corners swdCorner neuCorner where swdCorner = Vector3 (v3x split') (minY bbx) (v3z split') neuCorner = Vector3 (maxX bbx) (v3y split') (maxZ bbx) newBBox3 bbx split' NWU = bound_corners swdCorner neuCorner where swdCorner = Vector3 (minX bbx) (v3y split') (v3z split') neuCorner = Vector3 (v3x split') (maxY bbx) (maxZ bbx) newBBox3 bbx split' NEU = bound_corners swdCorner neuCorner where swdCorner = Vector3 (v3x split') (v3y split') (v3z split') neuCorner = Vector3 (maxX bbx) (maxY bbx) (maxZ bbx) -- | filterNodes is default function for BBoxConfig -- used to recurse down octree identifying which BBox3s contain DefInput filterNodes :: BBox3 -> DefInput -> Maybe DefInput filterNodes bbox x = if within_bounds x bbox then Just x else Nothing -- | points is default function for BBoxConfig -- pre-processes Leaf points :: BBox3 -> DefInput -> [LeafValue DefNodeValue ] -> DefOutput points box _ leaf = (box, leaf) -- | result reduces the list of all BBoxes containing the point to -- the terminal BBox result :: DefInput -> [DefOutput ] -> DefOutput result _ (x:xs) = foldl' findTerminal x xs where findTerminal :: DefOutput -> DefOutput -> DefOutput findTerminal bbox1@(bbox1',_) bbox2@(bbox2',_) | inclusive bbox1' bbox2' = bbox1 | otherwise = bbox2 -- | Supplied boolean test for result function -- Returns True if Box b1 is contained within Box b2 inclusive :: BBox3 -> BBox3 -> Bool inclusive b1 b2 = case isect b1 b2 of Just b3 -> b1 == b3 Nothing -> False