diff --git a/AC-Vector-Fancy.cabal b/AC-Vector-Fancy.cabal
--- a/AC-Vector-Fancy.cabal
+++ b/AC-Vector-Fancy.cabal
@@ -1,6 +1,6 @@
 Cabal-Version: >= 1.6
 Name:          AC-Vector-Fancy
-Version:       2.0.0
+Version:       2.1.0
 Stability:     Experimental
 Synopsis:      Fancy type system stuff for AC-Vector
 
@@ -10,7 +10,9 @@
   (Requires several language extensions, including
   type families.)
 
-Category:      Data, Math, Numerical
+  Now includes bounding box classes.
+
+Category:      Data, Math, Numerical, Graphics
 License:       BSD3
 License-file:  License.txt
 Author:        Andrew Coppin
@@ -22,6 +24,7 @@
   Exposed-modules:
     Data.Vector.Axis,
     Data.Vector.Fancy,
-    Data.Vector.Transform.Fancy
-  Build-Depends:   base >= 4 && < 5, AC-Angle >= 1.0, AC-Vector >= 2.0
+    Data.Vector.Transform.Fancy,
+    Data.BoundingBox
+  Build-Depends:   base >= 4 && < 5, AC-Angle >= 1.0, AC-Vector >= 2.1
   HS-Source-Dirs:  .
diff --git a/Data/BoundingBox.hs b/Data/BoundingBox.hs
new file mode 100644
--- /dev/null
+++ b/Data/BoundingBox.hs
@@ -0,0 +1,101 @@
+{- |
+  Bounding boxes of various numbers of dimensions, plus a class for generically handling them.
+-}
+
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.BoundingBox
+    (
+      -- * Class
+      BoundingBox (..),
+
+      -- * Types
+
+      -- ** 1 dimension
+      R.Range (), B1.BBox1 (),
+
+      -- ** 2 dimensions
+      B2.BBox2 (),
+
+      -- ** 3 dimensions
+      B3.BBox3 (),
+
+      -- ** 4 dimensions
+      B4.BBox4 ()
+    )
+  where
+
+import Data.Vector
+import qualified Data.BoundingBox.Range as R
+import qualified Data.BoundingBox.B1    as B1
+import qualified Data.BoundingBox.B2    as B2
+import qualified Data.BoundingBox.B3    as B3
+import qualified Data.BoundingBox.B4    as B4
+
+-- | Class for dealing with bounding boxes.
+class BoundingBox b where
+  -- | The type of vectors that this bounding box deals with.
+  type Point b :: *
+
+  -- | Given two corner points, construct a bounding box containing them both. (You can use any two points, given in any order, provided that they are from /opposite/ corners.)
+  bounds :: Point b -> Point b -> b
+
+  -- | Return a point containing the minimum values for all coordinates.
+  min_bound :: b -> Point b
+
+  -- | Return a point containing the maximum values for all coordinates.
+  max_bound :: b -> Point b
+
+  -- | Test whether a given point lies within a given bounding box.
+  within_bounds :: Point b -> b -> Bool
+
+  -- | Take the union of two bounding boxes. The result is a new bounding box that contains every point that the original pair of boxes contained, and probably some extra space as well.
+  union :: b -> b -> b
+
+  -- | Take the intersection of two bounding boxes. If the boxes do not overlap, return 'Nothing'. Otherwise return a bounding box containing only the points common to both original bounding boxes.
+  isect :: b -> b -> Maybe b
+
+instance BoundingBox R.Range where
+  type Point R.Range = Scalar
+  bounds        = R.bounds
+  min_bound     = R.min_bound
+  max_bound     = R.max_bound
+  within_bounds = R.within_bounds
+  union         = R.union
+  isect         = R.isect
+
+instance BoundingBox B1.BBox1 where
+  type Point B1.BBox1 = Vector1
+  bounds        = B1.bounds
+  min_bound     = B1.min_bound
+  max_bound     = B1.max_bound
+  within_bounds = B1.within_bounds
+  union         = B1.union
+  isect         = B1.isect
+
+instance BoundingBox B2.BBox2 where
+  type Point B2.BBox2 = Vector2
+  bounds        = B2.bounds
+  min_bound     = B2.min_bound
+  max_bound     = B2.max_bound
+  within_bounds = B2.within_bounds
+  union         = B2.union
+  isect         = B2.isect
+
+instance BoundingBox B3.BBox3 where
+  type Point B3.BBox3 = Vector3
+  bounds        = B3.bounds
+  min_bound     = B3.min_bound
+  max_bound     = B3.max_bound
+  within_bounds = B3.within_bounds
+  union         = B3.union
+  isect         = B3.isect
+
+instance BoundingBox B4.BBox4 where
+  type Point B4.BBox4 = Vector4
+  bounds        = B4.bounds
+  min_bound     = B4.min_bound
+  max_bound     = B4.max_bound
+  within_bounds = B4.within_bounds
+  union         = B4.union
+  isect         = B4.isect
