diff --git a/extern/typed-geometry b/extern/typed-geometry index a6c6371f1bac47f0f269032549adb1873d1f32e4..0c9b77eeb3b1e78e2054f69f15c3859fae6f84b6 160000 --- a/extern/typed-geometry +++ b/extern/typed-geometry @@ -1 +1 @@ -Subproject commit a6c6371f1bac47f0f269032549adb1873d1f32e4 +Subproject commit 0c9b77eeb3b1e78e2054f69f15c3859fae6f84b6 diff --git a/samples/04-object-properties/main.cc b/samples/04-object-properties/main.cc new file mode 100644 index 0000000000000000000000000000000000000000..3b56a04bd9f9068d4aae61e5aa5c4ecac319fe95 --- /dev/null +++ b/samples/04-object-properties/main.cc @@ -0,0 +1,169 @@ +#include <typed-geometry/tg.hh> + +#include <glow-extras/glfw/GlfwContext.hh> +#include <glow-extras/viewer/view.hh> + +template <class Obj> +void test_obj(Obj const& obj) +{ + tg::rng rng; + const int domainD = tg::object_traits<Obj>::domain_dimension; + const int objectD = tg::object_traits<Obj>::object_dimension; + if constexpr (tg::object_traits<Obj>::is_finite) + { + float size; + if constexpr (objectD == 3) + size = 1000.f + volume_of(obj); + else if constexpr (objectD == 2) + size = 500.f + area_of(obj); + else if constexpr (tg::object_traits<Obj>::is_boundary) + size = 100.f + perimeter_of(obj); + else + size = 100.f + length(obj); + + auto uniformPts = std::vector<tg::pos3>(); + for (tg::u64 i = 0; i < size; ++i) + uniformPts.emplace_back(uniform(rng, obj)); + + auto v = gv::view(); + + // uniform + gv::view(uniformPts, tg::to_string(obj)); + + // any_point + gv::view(gv::points(tg::pos3(any_point(obj))).point_size_px(12.f), tg::color4::red); + + // centroid + auto const centroid = centroid_of(obj); + if (any_point(obj) == centroid) + gv::view(gv::points(tg::pos3(centroid)).point_size_px(13.f), tg::color4::yellow); + else + gv::view(gv::points(tg::pos3(centroid)).point_size_px(12.f), tg::color4::green); + + // aabb_of + auto const aabb = aabb_of(obj); + if constexpr (domainD == 3) + gv::view(gv::lines(aabb)); + else + gv::view(gv::lines(tg::aabb3(tg::pos3(aabb.min), tg::pos3(aabb.max)))); + + // normal_of + if constexpr (domainD == 3 && ((objectD == 2 && !tg::object_traits<Obj>::is_boundary) || (objectD == 1 && tg::object_traits<Obj>::is_boundary))) + gv::view(tg::segment3(centroid, centroid + normal_of(obj)), tg::color4::green); + } +} + +int main() +{ + auto const test_obj_and_boundary = [](auto const& o) { + test_obj(o); + test_obj(boundary_of(o)); + }; + + auto const test_obj_and_boundary_no_caps = [](auto const& o) { + test_obj(o); + test_obj(boundary_of(o)); + test_obj(boundary_no_caps_of(o)); + }; + + glow::glfw::GlfwContext ctx; + tg::rng rng; + + auto const r = uniform(rng, 0.0f, 10.0f); + auto const h = uniform(rng, 0.0f, 10.0f); + auto const a = tg::uniform<tg::angle>(rng); + auto const n2 = tg::uniform<tg::dir2>(rng); + auto const n3 = tg::uniform<tg::dir3>(rng); + + auto const range2 = tg::aabb2(tg::pos2(-10), tg::pos2(10)); + auto const range3 = tg::aabb3(tg::pos3(-10), tg::pos3(10)); + + auto const pos20 = uniform(rng, range2); + auto const pos21 = uniform(rng, range2); + auto const pos22 = uniform(rng, range2); + + auto const pos30 = uniform(rng, range3); + auto const pos31 = uniform(rng, range3); + auto const pos32 = uniform(rng, range3); + + auto const axis0 = tg::segment3(pos30, pos31); + auto const disk0 = tg::sphere2in3(pos30, r, n3); + + auto const d1 = tg::uniform<tg::dir1>(rng); + auto m1 = tg::mat1(); + m1[0] = d1 * uniform(rng, 1.0f, 3.0f); + + auto const d20 = tg::uniform<tg::dir2>(rng); + auto const d21 = perpendicular(d20); + auto m2 = tg::mat2(); + m2[0] = d20 * uniform(rng, 1.0f, 3.0f); + m2[1] = d21 * uniform(rng, 1.0f, 3.0f); + + auto const d30 = tg::uniform<tg::dir3>(rng); + auto const d31 = any_normal(d30); + auto const d32 = normalize(cross(d30, d31)); + auto m3 = tg::mat3(); + m3[0] = d30 * uniform(rng, 1.0f, 3.0f); + m3[1] = d31 * uniform(rng, 1.0f, 3.0f); + m3[2] = d32 * uniform(rng, 1.0f, 3.0f); + + auto m23 = tg::mat2x3(); + m23[0] = d30 * uniform(rng, 1.0f, 3.0f); + m23[1] = d31 * uniform(rng, 1.0f, 3.0f); + + // aabb + test_obj_and_boundary(aabb_of(pos20, pos21)); + test_obj_and_boundary(aabb_of(pos30, pos31)); + // box + test_obj_and_boundary(tg::box2(pos20, m2)); + test_obj_and_boundary(tg::box3(pos30, m3)); + test_obj_and_boundary(tg::box2in3(pos30, m23)); + // capsule + test_obj_and_boundary(tg::capsule3(axis0, r)); + // cylinder + test_obj_and_boundary_no_caps(tg::cylinder3(axis0, r)); + // ellipse + test_obj_and_boundary(tg::ellipse2(pos20, m2)); + test_obj_and_boundary(tg::ellipse3(pos30, m3)); + test_obj_and_boundary(tg::ellipse2in3(pos30, m23)); + // halfspace + test_obj(tg::halfspace2(n2, h)); + test_obj(tg::halfspace3(n3, h)); + // hemisphere + test_obj_and_boundary_no_caps(tg::hemisphere2(pos20, r, n2)); + test_obj_and_boundary_no_caps(tg::hemisphere3(pos30, r, n3)); + // inf_cone + test_obj_and_boundary(tg::inf_cone2(pos20, n2, a)); + test_obj_and_boundary(tg::inf_cone3(pos30, n3, a)); + // inf_cylinder + test_obj_and_boundary(tg::inf_cylinder2(tg::line2(pos20, n2), r)); + test_obj_and_boundary(tg::inf_cylinder3(tg::line3(pos30, n3), r)); + // line + test_obj(tg::line2(pos20, n2)); + test_obj(tg::line3(pos30, n3)); + // plane + test_obj(tg::plane2(n2, h)); + test_obj(tg::plane3(n3, h)); + // pyramid + 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 + (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))); + // ray + test_obj(tg::ray2(pos20, n2)); + test_obj(tg::ray3(pos30, n3)); + // segment + test_obj(tg::segment2(pos20, pos21)); + test_obj(tg::segment3(pos30, pos31)); + // sphere + test_obj_and_boundary(tg::sphere2(pos20, r)); + test_obj_and_boundary(tg::sphere3(pos30, r)); + test_obj_and_boundary(tg::sphere2in3(pos30, r, n3)); + // triangle + test_obj(tg::triangle2(pos20, pos21, pos22)); + test_obj(tg::triangle3(pos30, pos31, pos32)); +}