diff --git a/dumux/common/geometry/boundingboxtree.hh b/dumux/common/geometry/boundingboxtree.hh
index 1b02e16d6b861beb5f222de2aae3d54c61812a67..a1cd4cf8b5b222ecd5f84891d2bccedfa43707af 100644
--- a/dumux/common/geometry/boundingboxtree.hh
+++ b/dumux/common/geometry/boundingboxtree.hh
@@ -351,9 +351,9 @@ inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
 {
     using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
     static constexpr ctype eps_ = 1.0e-7;
-    const ctype eps0 = eps_*(b[3] - b[0]);
-    const ctype eps1 = eps_*(b[4] - b[1]);
-    const ctype eps2 = eps_*(b[5] - b[2]);
+    const ctype eps0 = eps_*std::max(b[3]-b[0], a[3]-a[0]);
+    const ctype eps1 = eps_*std::max(b[4]-b[1], a[4]-a[1]);
+    const ctype eps2 = eps_*std::max(b[5]-b[2], a[5]-a[2]);
     return (b[0] - eps0 <= a[3] && a[0] <= b[3] + eps0 &&
             b[1] - eps1 <= a[4] && a[1] <= b[4] + eps1 &&
             b[2] - eps2 <= a[5] && a[2] <= b[5] + eps2);
@@ -370,8 +370,8 @@ inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
 {
     using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
     static constexpr ctype eps_ = 1.0e-7;
-    const ctype eps0 = eps_*(b[2] - b[0]);
-    const ctype eps1 = eps_*(b[3] - b[1]);
+    const ctype eps0 = eps_*std::max(b[2]-b[0], a[2]-a[0]);
+    const ctype eps1 = eps_*std::max(b[3]-b[1], a[3]-a[1]);
     return (b[0] - eps0 <= a[2] && a[0] <= b[2] + eps0 &&
             b[1] - eps1 <= a[3] && a[1] <= b[3] + eps1);
 }
@@ -386,7 +386,7 @@ inline bool intersectsBoundingBoxBoundingBox(const ctypea* a, const ctypeb* b)
 {
     using ctype = typename Dune::PromotionTraits<ctypea, ctypeb>::PromotedType;
     static constexpr ctype eps_ = 1.0e-1;
-    const ctype eps0 = eps_*(b[1] - b[0]);
+    const ctype eps0 = eps_*std::max(b[1]-b[0], a[1]-a[0]);
     return b[0] - eps0 <= a[1] && a[0] <= b[1] + eps0;
 }
 
diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt
index 8c8c1ee2e273e88e4d5050dac2158f6b83de742a..ea0bdb19633e37b326a1675139f36d13c0f6afd4 100644
--- a/test/common/CMakeLists.txt
+++ b/test/common/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(boundingboxtree)
+add_subdirectory(geometry)
 add_subdirectory(math)
 add_subdirectory(parameters)
 add_subdirectory(propertysystem)
diff --git a/test/common/boundingboxtree/test_bboxtree.cc b/test/common/boundingboxtree/test_bboxtree.cc
index 9da087f54995fb259544db481d034238d4fabfc8..cff08c9c82ee59db25a054c7c35ef78427fe683f 100644
--- a/test/common/boundingboxtree/test_bboxtree.cc
+++ b/test/common/boundingboxtree/test_bboxtree.cc
@@ -68,13 +68,26 @@ public:
     template <class OtherEntitySet, class OtherGridView>
     int intersectTree(const Dumux::BoundingBoxTree<OtherEntitySet>& otherTree,
                       const OtherGridView& otherGridView,
-                      std::size_t expectedIntersections)
+                      std::size_t expectedUniqueIntersections,
+                      bool checkTotalIntersections = false,
+                      std::size_t expectedIntersections = 0)
     {
         Dune::Timer timer;
         const auto intersections = intersectingEntities(*tree_, otherTree);
-        std::cout << "Computed tree intersections in " << timer.elapsed() << std::endl;
+        std::cout << "Computed " << intersections.size() << " tree intersections in " << timer.elapsed() << std::endl;
         timer.reset();
 
+        if (checkTotalIntersections)
+        {
+            if (intersections.size() != expectedIntersections)
+            {
+                std::cerr << "BoundingBoxTree intersection failed: Expected "
+                          << expectedIntersections << " (total) and got "
+                          << intersections.size() << "!" <<std::endl;
+                return 1;
+            }
+        }
+
         std::vector<std::vector<std::vector<GlobalPosition>>> map;
         map.resize(otherGridView.size(0));
         std::vector<std::vector<GlobalPosition>> uniqueIntersections;
@@ -96,10 +109,10 @@ public:
         std::cout << "Found " << uniqueIntersections.size() << " unique intersections "
                   << "in " << timer.elapsed() << std::endl;
 
-        if (uniqueIntersections.size() != expectedIntersections)
+        if (uniqueIntersections.size() != expectedUniqueIntersections)
         {
             std::cerr << "BoundingBoxTree intersection failed: Expected "
-                      << expectedIntersections << " and got "
+                      << expectedUniqueIntersections << " (unique) and got "
                       << uniqueIntersections.size() << "!" <<std::endl;
             return 1;
         }
@@ -168,37 +181,93 @@ int main (int argc, char *argv[]) try
 
             using NetworkGrid = Dune::FoamGrid<1, dimworld>;
             using NetworkGridView = NetworkGrid::LeafGridView;
+            using EntitySet = Dumux::GridViewGeometricEntitySet<NetworkGridView, 0>;
+            Dumux::BoundingBoxTree<EntitySet> networkTree;
 
-            std::cout << std::endl
-                          << "Intersect with other bounding box tree:" << std::endl
-                          << "***************************************"
-                          << std::endl;
+            {
+                std::cout << std::endl
+                              << "Intersect with other bounding box tree:" << std::endl
+                              << "***************************************"
+                              << std::endl;
 
-            auto networkGrid = std::shared_ptr<NetworkGrid>(Dune::GmshReader<NetworkGrid>::read("network1d.msh", false, false));
+                // create a network grid from gmsh
+                auto networkGrid = std::shared_ptr<NetworkGrid>(Dune::GmshReader<NetworkGrid>::read("network1d.msh", false, false));
 
-            // scaling
-            for (const auto& vertex : vertices(networkGrid->leafGridView()))
-            {
-                auto newPos = vertex.geometry().corner(0);
-                newPos *= scaling;
-                networkGrid->setPosition(vertex, newPos);
+                // scaling
+                for (const auto& vertex : vertices(networkGrid->leafGridView()))
+                {
+                    auto newPos = vertex.geometry().corner(0);
+                    newPos *= scaling;
+                    networkGrid->setPosition(vertex, newPos);
+                }
+
+                // Dune::VTKWriter<NetworkGridView> lowDimVtkWriter(networkGrid->leafGridView());
+                // lowDimVtkWriter.write("network", Dune::VTK::ascii);
+
+                std::cout << "Constructed 1d network grid with " << networkGrid->leafGridView().size(0) << " elements." << std::endl;
+
+                // build the bulk grid bounding box tree
+                returns.push_back(test.build(grid->leafGridView()));
+
+                // build the network grid bounding box tree
+                networkTree.build(std::make_shared<EntitySet>(networkGrid->leafGridView()));
+
+                // intersect the two bounding box trees
+                returns.push_back(test.intersectTree(networkTree, networkGrid->leafGridView(), 20));
             }
+            {
+                std::cout << std::endl
+                              << "Intersect with other bounding box tree (2):" << std::endl
+                              << "*******************************************"
+                              << std::endl;
 
-            // Dune::VTKWriter<NetworkGridView> lowDimVtkWriter(networkGrid->leafGridView());
-            // lowDimVtkWriter.write("network", Dune::VTK::ascii);
+                // construct a line network grid
+                const GlobalPosition lowerLeftNW({0.5, 0.5, 0.0});
+                const GlobalPosition upperRightNW({0.5, 0.5, 1.0});
 
-            std::cout << "Constructed 1d network grid with " << networkGrid->leafGridView().size(0) << " elements." << std::endl;
+                // make the grid (structured interval grid in dimworld space)
+                Dune::GridFactory<NetworkGrid> factory;
 
-            // build the bulk grid bounding box tree
-            returns.push_back(test.build(grid->leafGridView()));
+        #if DUNE_VERSION_NEWER(DUNE_COMMON,2,6)
+                constexpr auto geomType = Dune::GeometryTypes::line;
+        #else
+                auto geomType = Dune::GeometryType(1);
+        #endif
 
-            // build the network grid bounding box tree
-            using EntitySet = Dumux::GridViewGeometricEntitySet<NetworkGridView, 0>;
-            Dumux::BoundingBoxTree<EntitySet> networkTree;
-            networkTree.build(std::make_shared<EntitySet>(networkGrid->leafGridView()));
+                // create a step vector
+                auto step = upperRightNW;
+                step -= lowerLeftNW, step /= numCellsX;
+
+                // create the vertices
+                auto globalPos = lowerLeftNW;
+                for (unsigned int vIdx = 0; vIdx <= numCellsX; vIdx++, globalPos += step)
+                    factory.insertVertex(globalPos);
+
+                // create the cells
+                for(unsigned int eIdx = 0; eIdx < numCellsX; eIdx++)
+                    factory.insertElement(geomType, {eIdx, eIdx+1});
 
-            // intersect the two bounding box trees
-            returns.push_back(test.intersectTree(networkTree, networkGrid->leafGridView(), 20));
+                auto networkGrid = std::shared_ptr<NetworkGrid>(factory.createGrid());
+
+                // scaling
+                for (const auto& vertex : vertices(networkGrid->leafGridView()))
+                {
+                    auto newPos = vertex.geometry().corner(0);
+                    newPos *= scaling;
+                    networkGrid->setPosition(vertex, newPos);
+                }
+
+                std::cout << "Constructed 1d network grid with " << networkGrid->leafGridView().size(0) << " elements." << std::endl;
+
+                // build the bulk grid bounding box tree
+                returns.push_back(test.build(grid->leafGridView()));
+
+                // build the network grid bounding box tree
+                networkTree.build(std::make_shared<EntitySet>(networkGrid->leafGridView()));
+
+                // intersect the two bounding box trees
+                returns.push_back(test.intersectTree(networkTree, networkGrid->leafGridView(), 10, true, 40));
+            }
         }
 #endif
     }
diff --git a/test/common/geometry/CMakeLists.txt b/test/common/geometry/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..41465b6623d54694b5d64f7d47e63283cd2161ec
--- /dev/null
+++ b/test/common/geometry/CMakeLists.txt
@@ -0,0 +1,8 @@
+dune_add_test(SOURCES test_1d3d_intersection.cc)
+
+#install sources
+install(FILES
+test_1d3d_intersection.cc
+DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/test/common/geometry)
+
+set(CMAKE_BUILD_TYPE Release)
diff --git a/test/common/geometry/test_1d3d_intersection.cc b/test/common/geometry/test_1d3d_intersection.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8f7cf4d6ca249a33ce46dec3b612002d26056cfa
--- /dev/null
+++ b/test/common/geometry/test_1d3d_intersection.cc
@@ -0,0 +1,118 @@
+#include <config.h>
+
+#include <iostream>
+#include <algorithm>
+#include <initializer_list>
+
+#include <dune/common/exceptions.hh>
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/fvector.hh>
+#include <dune/geometry/multilineargeometry.hh>
+
+#include <dumux/common/geometry/geometryintersection.hh>
+
+
+#ifndef DOXYGEN
+template<int dimworld = 3>
+Dune::MultiLinearGeometry<double, 1, dimworld>
+makeLine(std::initializer_list<Dune::FieldVector<double, dimworld>>&& c)
+{
+    return {Dune::GeometryTypes::line, c};
+}
+
+template<int dimworld = 3>
+bool testIntersection(const Dune::MultiLinearGeometry<double, dimworld, dimworld>& cube,
+                      const Dune::MultiLinearGeometry<double, 1, dimworld>& line,
+                      bool foundExpected = true)
+{
+    using Test = Dumux::GeometryIntersection<Dune::MultiLinearGeometry<double,dimworld,dimworld>,
+                                             Dune::MultiLinearGeometry<double,1,dimworld> >;
+    typename Test::IntersectionType intersection;
+    bool found = Test::intersection(cube, line, intersection);
+    if (!found && foundExpected)
+        std::cerr << "Failed detecting intersection with " << line.corner(0) << " " << line.corner(1) << std::endl;
+    else if (found && foundExpected)
+        std::cout << "Found intersection with " << line.corner(0) << " " << line.corner(1) << std::endl;
+    else if (found && !foundExpected)
+        std::cerr << "Found false positive: intersection with " << line.corner(0) << " " << line.corner(1) << std::endl;
+    else if (!found && !foundExpected)
+        std::cout << "No intersection with " << line.corner(0) << " " << line.corner(1) << std::endl;
+    return (found == foundExpected);
+}
+#endif
+
+int main (int argc, char *argv[]) try
+{
+    // maybe initialize mpi
+    Dune::MPIHelper::instance(argc, argv);
+
+    constexpr int dimworld = 3;
+    constexpr int dim = 3;
+
+    std::vector<Dune::FieldVector<double, dimworld>> cubeCorners({
+        {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0},
+        {0.0, 0.0, 1.0}, {1.0, 0.0, 1.0}, {0.0, 1.0, 1.0}, {1.0, 1.0, 1.0}
+    });
+
+    Dune::MultiLinearGeometry<double, dim, dimworld>
+        cube(Dune::GeometryTypes::cube(dimworld), cubeCorners);
+
+
+
+    // collect returns to determine exit code
+    std::vector<bool> returns;
+
+    // the tests
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 0.0}, {1.0, 0.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 0.0}, {0.0, 1.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 0.0}, {1.0, 1.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 0.0}, {1.0, 0.0, 0.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 1.0}, {1.0, 0.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 1.0}, {0.0, 1.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 1.0}, {0.0, 0.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 0.0, 1.0}, {1.0, 1.0, 1.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 1.0}, {0.0, 0.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 1.0}, {0.0, 1.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 1.0, 1.0}, {1.0, 1.0, 1.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 1.0}, {1.0, 1.0, 0.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 1.0}, {0.0, 1.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 1.0}, {1.0, 0.0, 1.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{0.0, 0.0, 0.0}, {1.0, 1.0, 1.0}})));
+    returns.push_back(testIntersection(cube, makeLine({{0.5, 0.5, 0.5}, {0.5, 0.5, -2.0}})));
+
+    returns.push_back(testIntersection(cube, makeLine({{0.5, 0.5, 0.0}, {0.5, 0.5, -2.0}}), false));
+    returns.push_back(testIntersection(cube, makeLine({{1.0, 1.0, 1.0}, {2.0, 2.0, 2.0}}), false));
+
+    // determine the exit code
+    if (std::any_of(returns.begin(), returns.end(), [](bool i){ return !i; }))
+        return 1;
+
+    std::cout << "All tests passed!" << std::endl;
+
+    return 0;
+}
+// //////////////////////////////////
+//   Error handler
+// /////////////////////////////////
+catch (const Dune::Exception& e) {
+    std::cout << e << std::endl;
+    return 1;
+}