diff --git a/extern/typed-geometry b/extern/typed-geometry
index 05a25760acd58e2a87d3627a2f6d3d9f40ecc95e..674fb112732a1a08d5abd237abc0f2a45580ad7f 160000
--- a/extern/typed-geometry
+++ b/extern/typed-geometry
@@ -1 +1 @@
-Subproject commit 05a25760acd58e2a87d3627a2f6d3d9f40ecc95e
+Subproject commit 674fb112732a1a08d5abd237abc0f2a45580ad7f
diff --git a/tests/feature/intersections/ray-intersect.cc b/tests/feature/intersections/ray-intersect.cc
index 0c79c41d12bbb7fd971b60b15704df3ea2122cb2..bc352d86f00157d33a0d9707f7d567f61ce4f411 100644
--- a/tests/feature/intersections/ray-intersect.cc
+++ b/tests/feature/intersections/ray-intersect.cc
@@ -8,7 +8,7 @@ TG_FUZZ_TEST(TypedGeometry, Intersections)
         for (const auto& t : ts)
         {
             const auto ip = ray[t];
-            CHECK(contains(obj, ip, tolerance));
+            CHECK(contains(obj, ip, tolerance * tg::sqrt(t)));
         }
         const auto t = tg::closest_intersection_parameter(ray, obj);
         if (t.has_value())
@@ -38,7 +38,7 @@ TG_FUZZ_TEST(TypedGeometry, Intersections)
             const auto ip3 = ray[interval.end];
             CHECK(contains(obj, ip1, tolerance));
             CHECK(contains(obj, ip2, tolerance));
-            CHECK(contains(obj, ip3, tolerance));
+            CHECK(contains(obj, ip3, tolerance * tg::sqrt(interval.end)));
 
             const auto t = tg::closest_intersection_parameter(ray, obj);
             CHECK(t.has_value());
@@ -126,6 +126,7 @@ TG_FUZZ_TEST(TypedGeometry, Intersections)
     const auto pos41 = uniform(rng, range4);
 
     const auto axis0 = tg::segment3(pos30, pos31);
+    const auto disk0 = tg::sphere2in3(pos30, r, n3);
 
     const auto d1 = tg::uniform<tg::dir1>(rng);
     auto m1 = tg::mat1();
@@ -170,6 +171,10 @@ TG_FUZZ_TEST(TypedGeometry, Intersections)
     // cylinder
     test_obj_and_boundary_no_caps(ray3, tg::cylinder<3, float>(axis0, r));
     // ellipse
+    test_obj_and_boundary(ray1, tg::ellipse1(pos10, m1));
+    test_obj_and_boundary(ray2, tg::ellipse2(pos20, m2));
+    test_obj_and_boundary(ray3, tg::ellipse3(pos30, m3));
+    // TODO: ellipse4
     test_obj(ray3, tg::ellipse2in3(pos30, m23));
     // halfspace
     test_solid_obj(ray1, tg::halfspace1(n1, h));
@@ -194,6 +199,12 @@ TG_FUZZ_TEST(TypedGeometry, Intersections)
     test_obj(ray2, tg::plane2(n2, h));
     test_obj(ray3, tg::plane3(n3, h));
     test_obj(ray4, tg::plane4(n4, h));
+    // pyramid
+    test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
+    test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone
+    test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
+    test_obj(ray3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
+    // test_obj_and_boundary_no_caps(ray3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
     // ray
     test_obj(ray2, tg::ray2(pos20, n2));
     // segment
diff --git a/tests/feature/objects/aabb.cc b/tests/feature/objects/aabb.cc
index 9d1e8481df5d33a21c621b11680657073a71e88a..68362862060697c083e5aa561bf6748363751c2b 100644
--- a/tests/feature/objects/aabb.cc
+++ b/tests/feature/objects/aabb.cc
@@ -111,7 +111,7 @@ TG_FUZZ_TEST(TypedGeometry, ObjectAABB)
     // test_obj(p4, tg::hemisphere4(pos40, r, n4));
     // pyramid
     test_obj(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
-    //test_obj(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: uniform(quad) missing
+    //test_obj(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: uniform(quad) missing
     test_obj(tg::pyramid<tg::sphere2in3>(tg::sphere2in3(pos30, r, n3), h)); // == cone
     test_obj(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
     // TODO: test for quad require uniform(quad)
diff --git a/tests/feature/objects/any_point.cc b/tests/feature/objects/any_point.cc
index b616a1e393b4e3ecd031e9b7cd1bbff3b3bd20bb..00109c30561067379184db94a99818899338db04 100644
--- a/tests/feature/objects/any_point.cc
+++ b/tests/feature/objects/any_point.cc
@@ -122,8 +122,8 @@ TG_FUZZ_TEST(TypedGeometry, AnyPoint)
     test_obj_and_boundary_no_caps(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
     test_obj_and_boundary_no_caps(tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone
     test_obj_and_boundary_no_caps(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
-    test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h));
-    // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h));
+    test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
+    // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
     // TODO: quad
     // test_obj(tg::quad2(pos20, pos21, pos22, pos23));
     // test_obj(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)));
diff --git a/tests/feature/objects/centroid.cc b/tests/feature/objects/centroid.cc
index 901734fc972b8447bc4384353c25e718ac50be81..03b7055def35706adb29ec4dc2920aa7cbe7b85f 100644
--- a/tests/feature/objects/centroid.cc
+++ b/tests/feature/objects/centroid.cc
@@ -173,8 +173,8 @@ TG_FUZZ_TEST(TypedGeometry, CentroidByUniform)
     test_obj_and_boundary_no_caps(tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
     test_obj_and_boundary_no_caps(tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone
     test_obj_and_boundary_no_caps(tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
-    // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: area(quad) missing
-    test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h));
+    // test_obj_and_boundary_no_caps(tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: area(quad) missing
+    test_obj(tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
     // TODO: quad
     // segment
     test_obj(tg::segment1(pos10, pos11));
diff --git a/tests/feature/objects/project.cc b/tests/feature/objects/project.cc
index 99ade853dbce947adfc90746c008a5ae66e0af4f..72bb5d256193eddd5105331c0a9f29b99979d443 100644
--- a/tests/feature/objects/project.cc
+++ b/tests/feature/objects/project.cc
@@ -121,8 +121,8 @@ TG_FUZZ_TEST_MAX_ITS_MAX_CYCLES(TypedGeometry, Project, 25, 100'000'000'000)
     test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
     test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone
     test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
-    // test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: project(quad) missing
-    test_obj(p3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h));
+    // test_obj_and_boundary_no_caps(p3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: project(quad) missing
+    test_obj(p3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
     // TODO: quad
     // segment
     test_obj(p1, tg::segment1(pos10, pos11));
diff --git a/tests/feature/random/uniform.cc b/tests/feature/random/uniform.cc
index 26413c5adc2b57380450c9d95d179915e0f85d22..fbba9ec5399229f1f0941f0abe0d48c6df460185 100644
--- a/tests/feature/random/uniform.cc
+++ b/tests/feature/random/uniform.cc
@@ -152,8 +152,8 @@ TG_FUZZ_TEST_MAX_ITS(TypedGeometry, UniformGeneralProperties, 100)
     test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::box2in3>(tg::box2in3(pos30, m23), h));
     test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::sphere2in3>(disk0, h)); // == cone
     test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::triangle3>(tg::triangle3(pos30, pos31, pos32), h));
-    // test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h)); // TODO: uniform(quad) missing
-    test_obj(samples3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos31 - pos30)), h));
+    // test_obj_and_boundary_no_caps(samples3, tg::pyramid<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h)); // TODO: uniform(quad) missing
+    test_obj(samples3, tg::pyramid_boundary_no_caps<tg::quad3>(tg::quad3(pos30, pos31, pos32, pos32 + (pos30 - pos31)), h));
     // TODO: quad
     // segment
     test_obj(samples1, tg::segment1(pos10, pos11));