diff --git a/test/geometry/test_2d3d_intersection.cc b/test/geometry/test_2d3d_intersection.cc
index 7bd05ed525a24eb25b838711fd915ab388b4016c..bf06825c0d4b01dafcdafc10d1cbd12158902c31 100644
--- a/test/geometry/test_2d3d_intersection.cc
+++ b/test/geometry/test_2d3d_intersection.cc
@@ -48,157 +48,201 @@ void testSegTriangle(const Dune::FieldVector<double, dimworld>& a,
     }
 }
 
-int main(int argc, char* argv[])
+template<typename ctype>
+auto makeUnitCube(ctype scale = 1.0)
 {
-    constexpr int dimworld = 3;
-    using Point = Dune::FieldVector<double, dimworld>;
-
-    Point a{0.0, 0.0, 0.1};
-    Point b{1.0, 0.0, 0.0};
-    Point c{0.0, 1.0, 0.0};
-
-    Point p0{0.5, 0.5, -1.0};
-    Point q0{0.5, 0.5, 1.0};
-
-    testSegTriangle(a, b, c, p0, q0);
-    testSegTriangle(a, b, c, q0, p0);
-
-    Point p1 = a;
-    Point q1 = b;
+    using CubeGeometry = Dune::MultiLinearGeometry<ctype, 3, 3>;
+    using GlobalPosition = typename CubeGeometry::GlobalCoordinate;
+
+    const auto unit = scale*1.0;
+    return CubeGeometry(
+        Dune::GeometryTypes::cube(3),
+        std::vector<GlobalPosition>({
+            {0.0, 0.0, 0.0},  {unit, 0.0, 0.0},  {0.0, unit, 0.0},  {unit, unit, 0.0},
+            {0.0, 0.0, unit}, {unit, 0.0, unit}, {0.0, unit, unit}, {unit, unit, unit}
+        })
+    );
+}
 
-    testSegTriangle(a, b, c, p1, q1, false);
-    testSegTriangle(a, b, c, q1, p1, false);
+template<typename ctype>
+auto makeHorizontalQuad(ctype scale = 1.0, ctype zPositionUnscaled = 1.0)
+{
+    using QuadGeometry = Dune::MultiLinearGeometry<ctype, 2, 3>;
+    using GlobalPosition = typename QuadGeometry::GlobalCoordinate;
+
+    zPositionUnscaled *= scale;
+    const auto unit = scale*1.0;
+    return QuadGeometry(
+        Dune::GeometryTypes::cube(2),
+        std::vector<GlobalPosition>({
+            {0.0, 0.0, zPositionUnscaled},  {unit, 0.0, zPositionUnscaled},
+            {0.0, unit, zPositionUnscaled}, {unit, unit, zPositionUnscaled}
+        })
+    );
+}
 
-    Point p2{0.0, 0.0, 0.0};
-    Point q2{0.0, 0.0, 0.2};
+template<typename ctype>
+auto makeInclinedTriangle(ctype scale = 1.0)
+{
+    using TriaGeometry = Dune::MultiLinearGeometry<ctype, 2, 3>;
+    using GlobalPosition = typename TriaGeometry::GlobalCoordinate;
+    return TriaGeometry(
+        Dune::GeometryTypes::simplex(2),
+        std::vector<GlobalPosition>({
+            {-0.1*scale, -0.1*scale, 0.3*scale},
+            {1.1*scale,  -0.1*scale, 0.3*scale},
+            {0.5*scale,   2.0*scale, 0.8*scale}
+        })
+    );
+}
 
-    testSegTriangle(a, b, c, p2, q2);
+int main(int argc, char* argv[])
+{
+    constexpr int dimworld = 3;
+    using Point = Dune::FieldVector<double, dimworld>;
 
-    using Geometry3D = Dune::MultiLinearGeometry<double, 3, dimworld>;
-    using Geometry2D = Dune::MultiLinearGeometry<double, 2, dimworld>;
-    using Test = Dumux::GeometryIntersection<Geometry3D, Geometry2D>;
-    typename Test::Intersection intersectionPolygon;
+    for (auto scale : {1.0, 1e3, 1e12, 1e-12})
+    {
+        std::cout << "Testing scale " << scale << std::endl;
 
-    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}
-    });
+        const Point a{0.0*scale, 0.0*scale, 0.1*scale};
+        const Point b{1.0*scale, 0.0*scale, 0.0*scale};
+        const Point c{0.0*scale, 1.0*scale, 0.0*scale};
 
-    std::vector<Dune::FieldVector<double, dimworld>> quadCorners({
-        {0.0, 0.0, 0.5}, {1.0, 0.0, 0.5}, {0.0, 1.0, 0.5}, {1.0, 1.0, 0.5}
-    });
+        const Point p0{0.5*scale, 0.5*scale, -1.0*scale};
+        const Point q0{0.5*scale, 0.5*scale, 1.0*scale};
 
-    std::vector<Dune::FieldVector<double, dimworld>> triCorners({
-        {-0.1, -0.1, 0.3}, {1.1, -0.1, 0.3}, {0.5, 2.0, 0.8}
-    });
+        testSegTriangle(a, b, c, p0, q0);
+        testSegTriangle(a, b, c, q0, p0);
 
-    Geometry3D cube(Dune::GeometryTypes::cube(dimworld), cubeCorners);
-    Geometry2D quad(Dune::GeometryTypes::cube(dimworld-1), quadCorners);
-    Geometry2D tri(Dune::GeometryTypes::simplex(dimworld-1), triCorners);
+        const Point p1 = a;
+        const Point q1 = b;
 
-    if (Test::intersection(cube, quad, intersectionPolygon))
-    {
-        const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
-        Dumux::writeVTKPolyDataTriangle(triangulation, "quad_intersections");
-        if (triangulation.size() != 4)
-            DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 4 intersections!");
-    }
-    else
-        DUNE_THROW(Dune::InvalidStateException, "No intersections found!");
+        testSegTriangle(a, b, c, p1, q1, false);
+        testSegTriangle(a, b, c, q1, p1, false);
 
-    if (Test::intersection(cube, tri, intersectionPolygon))
-    {
-        const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
-        Dumux::writeVTKPolyDataTriangle(triangulation, "tri_intersections");
-        if (triangulation.size() != 6)
-            DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 6 intersections!");
-    }
-    else
-        DUNE_THROW(Dune::InvalidStateException, "No intersections found!");
-
-    // Test a tricky situation intersecting a hexagon with two quadrilaterals.
-    // One face of the hexagon is in-plane with the two quadrilaterals, which
-    // together enclose the entire hexagon face. Thus, the sum of the areas of
-    // the two intersections must be equal to that of the respective hexagon face.
-    // The separating edge between the two quadrilaterals passes very close by one
-    // of the hex face corners. This situation was taken from an actual mortar
-    // application which exposed a bug in the 1d-2d algorithm in 3d space.
-    std::vector<Dune::FieldVector<double, dimworld>> hexCorners({
-        {0.8619712261141845, 1.206565697102448, 0.4152254463380627},
-        {0.8715547951379876, 1.175481516085758, 0.2599429674402531},
-        {0.7046736652858085, 1.209207158782034, 0.4447521639960824},
-        {0.7307137896935333, 1.171606500732276, 0.2574814772189353},
-        {0.8926414294658755, 1.0,               0.4012781039132332},
-        {0.8316315415883838, 1.0,               0.2581023823497354},
-        {0.7349272235105835, 1.0,               0.4613391568883559},
-        {0.7479805294570721, 1.0,               0.3155931875126768}
-    });
-
-    std::vector<Dune::FieldVector<double, dimworld>> quad1Corners({
-        {1.000000000000000000000000000000, 1.0, 1.000000000000000000000000000000},
-        {1.000000000000000000000000000000, 1.0, 0.327819111366782434124900191819},
-        {0.303996171086607036571081152942, 1.0, 1.000000000000000000000000000000},
-        {0.297170743844278550938042826601, 1.0, 0.293625720570556747457402479995}
-    });
-
-    std::vector<Dune::FieldVector<double, dimworld>> quad2Corners({
-        {1.000000000000000000000000000000, 1.0, 0.327819111366782434124900191819},
-        {1.000000000000000000000000000000, 1.0, 0.000000000000000000000000000000},
-        {0.297170743844278550938042826601, 1.0, 0.293625720570556747457402479995},
-        {0.325413399309280815252520824288, 1.0, 0.000000000000000000000000000000}
-    });
-
-    Geometry3D hex(Dune::GeometryTypes::cube(dimworld), hexCorners);
-    Geometry2D quad1(Dune::GeometryTypes::cube(dimworld-1), quad1Corners);
-    Geometry2D quad2(Dune::GeometryTypes::cube(dimworld-1), quad2Corners);
-
-    // lambda to compute the area of a triangulated intersection
-    auto computeArea = [] (const auto& triangulation)
-    {
-        double a = 0.0;
-        for (const auto& t : triangulation)
-            a += Geometry2D(Dune::GeometryTypes::simplex(dimworld-1),
-                            std::vector<Point>(t.begin(), t.end())).volume();
-        return a;
-    };
-
-    double area = 0.0;
-    if (Test::intersection(hex, quad1, intersectionPolygon))
-    {
-        const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
-        Dumux::writeVTKPolyDataTriangle(triangulation, "quad1_intersections");
-        if (triangulation.size() != 5)
-            DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 5 intersections!");
+        const Point p2{0.0*scale, 0.0*scale, 0.0*scale};
+        const Point q2{0.0*scale, 0.0*scale, 0.2*scale};
 
-        area += computeArea(triangulation);
-    }
+        testSegTriangle(a, b, c, p2, q2);
 
-    if (Test::intersection(hex, quad2, intersectionPolygon))
-    {
-        const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
-        Dumux::writeVTKPolyDataTriangle(triangulation, "quad2_intersections");
-        if (triangulation.size() != 1)
-            DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 1 intersections!");
+        const auto cube = makeUnitCube(scale);
+        const auto quad = makeHorizontalQuad(scale, 0.5);
+        using Geometry3D = decltype(cube);
+        using Geometry2D = decltype(quad);
+        using Test = Dumux::GeometryIntersection<Geometry3D, Geometry2D>;
+        typename Test::Intersection intersectionPolygon;
 
-        area += computeArea(triangulation);
+        if (Test::intersection(cube, quad, intersectionPolygon))
+        {
+            const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
+            Dumux::writeVTKPolyDataTriangle(triangulation, "quad_intersections");
+            if (triangulation.size() != 4)
+                DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 4 intersections!");
+        }
+        else
+            DUNE_THROW(Dune::InvalidStateException, "No intersections found!");
+
+        // quad that is slightly above the cube
+        const auto close_quad = makeHorizontalQuad(scale, 1.0+1e-6);
+        if (Test::intersection(cube, close_quad, intersectionPolygon))
+            DUNE_THROW(Dune::InvalidStateException, "Found unexpected intersection with close quad");
+
+        const auto tri = makeInclinedTriangle(scale);
+        if (Test::intersection(cube, tri, intersectionPolygon))
+        {
+            const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
+            Dumux::writeVTKPolyDataTriangle(triangulation, "tri_intersections");
+            if (triangulation.size() != 6)
+                DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 6 intersections!");
+        }
+        else
+            DUNE_THROW(Dune::InvalidStateException, "No intersections found!");
+
+        // Test a tricky situation intersecting a hexagon with two quadrilaterals.
+        // One face of the hexagon is in-plane with the two quadrilaterals, which
+        // together enclose the entire hexagon face. Thus, the sum of the areas of
+        // the two intersections must be equal to that of the respective hexagon face.
+        // The separating edge between the two quadrilaterals passes very close by one
+        // of the hex face corners. This situation was taken from an actual mortar
+        // application which exposed a bug in the 1d-2d algorithm in 3d space.
+        std::vector<Dune::FieldVector<double, dimworld>> hexCorners({
+            {0.8619712261141845*scale, 1.206565697102448*scale, 0.4152254463380627*scale},
+            {0.8715547951379876*scale, 1.175481516085758*scale, 0.2599429674402531*scale},
+            {0.7046736652858085*scale, 1.209207158782034*scale, 0.4447521639960824*scale},
+            {0.7307137896935333*scale, 1.171606500732276*scale, 0.2574814772189353*scale},
+            {0.8926414294658755*scale, 1.0*scale,               0.4012781039132332*scale},
+            {0.8316315415883838*scale, 1.0*scale,               0.2581023823497354*scale},
+            {0.7349272235105835*scale, 1.0*scale,               0.4613391568883559*scale},
+            {0.7479805294570721*scale, 1.0*scale,               0.3155931875126768*scale}
+        });
+
+        std::vector<Dune::FieldVector<double, dimworld>> quad1Corners({
+            {1.000000000000000000000000000000*scale, 1.0*scale, 1.000000000000000000000000000000*scale},
+            {1.000000000000000000000000000000*scale, 1.0*scale, 0.327819111366782434124900191819*scale},
+            {0.303996171086607036571081152942*scale, 1.0*scale, 1.000000000000000000000000000000*scale},
+            {0.297170743844278550938042826601*scale, 1.0*scale, 0.293625720570556747457402479995*scale}
+        });
+
+        std::vector<Dune::FieldVector<double, dimworld>> quad2Corners({
+            {1.000000000000000000000000000000*scale, 1.0*scale, 0.327819111366782434124900191819*scale},
+            {1.000000000000000000000000000000*scale, 1.0*scale, 0.000000000000000000000000000000*scale},
+            {0.297170743844278550938042826601*scale, 1.0*scale, 0.293625720570556747457402479995*scale},
+            {0.325413399309280815252520824288*scale, 1.0*scale, 0.000000000000000000000000000000*scale}
+        });
+
+        Geometry3D hex(Dune::GeometryTypes::cube(dimworld), hexCorners);
+        Geometry2D quad1(Dune::GeometryTypes::cube(dimworld-1), quad1Corners);
+        Geometry2D quad2(Dune::GeometryTypes::cube(dimworld-1), quad2Corners);
+
+        // lambda to compute the area of a triangulated intersection
+        auto computeArea = [] (const auto& triangulation)
+        {
+            double a = 0.0;
+            for (const auto& t : triangulation)
+                a += Geometry2D(Dune::GeometryTypes::simplex(dimworld-1),
+                                std::vector<Point>(t.begin(), t.end())).volume();
+            return a;
+        };
+
+        double area = 0.0;
+        if (Test::intersection(hex, quad1, intersectionPolygon))
+        {
+            const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
+            Dumux::writeVTKPolyDataTriangle(triangulation, "quad1_intersections");
+            if (triangulation.size() != 5)
+                DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 5 intersections!");
+
+            area += computeArea(triangulation);
+        }
+
+        if (Test::intersection(hex, quad2, intersectionPolygon))
+        {
+            const auto triangulation = Dumux::triangulate<2, dimworld>(intersectionPolygon);
+            Dumux::writeVTKPolyDataTriangle(triangulation, "quad2_intersections");
+            if (triangulation.size() != 1)
+                DUNE_THROW(Dune::InvalidStateException, "Found " << triangulation.size() << " instead of 1 intersections!");
+
+            area += computeArea(triangulation);
+        }
+
+        // compute area of the intersecting hexagon face
+        std::vector<Dune::FieldVector<double, dimworld>> hexFaceCorners({
+            {0.8926414294658755*scale, 1.0*scale, 0.4012781039132332*scale},
+            {0.8316315415883838*scale, 1.0*scale, 0.2581023823497354*scale},
+            {0.7349272235105835*scale, 1.0*scale, 0.4613391568883559*scale},
+            {0.7479805294570721*scale, 1.0*scale, 0.3155931875126768*scale}
+        });
+        Geometry2D hexFace(Dune::GeometryTypes::cube(dimworld-1), hexFaceCorners);
+        const auto hexFaceArea = hexFace.volume();
+
+        using std::abs;
+        const auto areaMismatch = abs(area-hexFaceArea);
+        std::cout << "Area mismatch is: " << areaMismatch << std::endl;
+        if (areaMismatch > hexFaceArea*1e-7)
+            DUNE_THROW(Dune::InvalidStateException, "Intersection area mismatch too large!");
     }
 
-    // compute area of the intersecting hexagon face
-    std::vector<Dune::FieldVector<double, dimworld>> hexFaceCorners({
-        {0.8926414294658755, 1.0, 0.4012781039132332},
-        {0.8316315415883838, 1.0, 0.2581023823497354},
-        {0.7349272235105835, 1.0, 0.4613391568883559},
-        {0.7479805294570721, 1.0, 0.3155931875126768}
-    });
-    Geometry2D hexFace(Dune::GeometryTypes::cube(dimworld-1), hexFaceCorners);
-    const auto hexFaceArea = hexFace.volume();
-
-    using std::abs;
-    const auto areaMismatch = abs(area-hexFaceArea);
-    std::cout << "Area mismatch is: " << areaMismatch << std::endl;
-    if (areaMismatch > 1e-14)
-        DUNE_THROW(Dune::InvalidStateException, "Intersection area mismatch too large!");
-
     std::cout << "All tests passed!" << std::endl;
 
     return 0;