From a7f5c0b286ba29cdd586f418638e9ab4a406bf97 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 24 Aug 2011 10:53:28 -0400 Subject: [PATCH] Change "find_containing_cubes" to "find_containing_cube" and speed it up considerably. --- src/Grid.hs | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Grid.hs b/src/Grid.hs index 3d636b5..517e3b1 100644 --- a/src/Grid.hs +++ b/src/Grid.hs @@ -11,7 +11,6 @@ import FunctionValues import Misc (flatten) import Point (Point) import Tetrahedron (polynomial) -import ThreeDimensional (contains_point) import Values (Values3D, dims, empty3d, zoom_shape) import qualified Data.Array.Repa as R @@ -73,14 +72,37 @@ cube_at g i j k | otherwise = Just $ (((cubes g) !! i) !! j) !! k --- | Takes a 'Grid', and returns all 'Cube's belonging to it that --- contain the given 'Point'. -find_containing_cubes :: Grid -> Point -> [Cube] -find_containing_cubes g p = - filter contains_our_point all_cubes + +-- The first cube along any axis covers (-h/2, h/2). The second +-- covers (h/2, 3h/2). The third, (3h/2, 5h/2), and so on. +-- +-- We translate the (x,y,z) coordinates forward by 'h' so that the +-- first covers (0, h), the second covers (h, 2h), etc. This makes +-- it easy to figure out which cube contains the given point. +calculate_containing_cube_coordinate :: Grid -> Double -> Int +calculate_containing_cube_coordinate g coord + -- Don't use a cube on the boundary if we can help it. + | coord == delta && (xsize > 0 && ysize > 0 && zsize > 0) = 1 + | otherwise = (ceiling ( (coord + delta) / cube_width )) - 1 + where + (xsize, ysize, zsize) = dims (function_values g) + delta = (h g) + cube_width = 2 * delta + + +-- | Takes a 'Grid', and returns a 'Cube' containing the given 'Point'. +-- Since our grid is rectangular, we can figure this out without having +-- to check every cube. +find_containing_cube :: Grid -> Point -> Cube +find_containing_cube g p = + case cube_at g i j k of + Just c -> c + Nothing -> error "No cube contains the given point." where - all_cubes = flatten $ cubes g - contains_our_point = flip contains_point p + (x, y, z) = p + i = calculate_containing_cube_coordinate g x + j = calculate_containing_cube_coordinate g y + k = calculate_containing_cube_coordinate g z zoom :: Grid -> Int -> Values3D @@ -101,6 +123,6 @@ zoom g scale_factor j' = fromIntegral j k' = fromIntegral k p = (i', j', k') :: Point - c = head (find_containing_cubes g p) + c = find_containing_cube g p t = head (find_containing_tetrahedra c p) f = polynomial t -- 2.43.2