/// @file /// @brief Task3: implementation #include "task3.hpp" // task3::generate_double_annulus #include "task2.hpp" // task2::select, task2::select_union #include "TriangleMesh.hpp" // ex5::TriangleMesh #include // for std::sqrt namespace task3 { using namespace task2; /// @todo Implement function 'generate_double_annulus' as declared and specified in task3.hpp /// Implementation Hints: /// - calculate the required bounding box for the annuluses using the centers coordinates +- outer radius /// - create a triangle mesh using the desired bounding box and resolution (h) /// - use the source code of task2.test.cpp for ideas how to create the boolean functions for circular regions /// - select the union of the two inner circles and remove the triangles using the following functions: /// mesh.getVertices /// task2::select_union(...) /// mesh.remove_vertices(...) /// - analoguously, select the union of the two outer circles and remove the INVERSE of this union using /// - mesh.getVertices() /// - task2::select_union(..., true) /// - mesh.remove_vertices(...) /// @brief Generates a triangle mesh placed of two (potentially merged) annuluses (Kreisringe) /// @param c1 Center coordinate of the first annulus /// @param c2 Center coordinate of the second annulus /// @param r inner radius of both annuluses /// @param R outer radius of both annuluses /// @param h lower bound for the triangle egde length of the resulting mesh /// @return Resulting triangle mesh ex5::TriangleMesh generate_double_annulus(task2::Vec2d c1, task2::Vec2d c2, double r, double R, double h) { // Calculate bounding box based on center coordinates, radii and a small offset double offset = h / 2.0; // Adjust as needed auto bb_min = task2::Vec2d{std::min(c1[0], c2[0]) - R - offset, std::min(c1[1], c2[1]) - R - offset}; auto bb_max = task2::Vec2d{std::max(c1[0], c2[0]) + R + offset, std::max(c1[1], c2[1]) + R + offset}; // Create triangle mesh using bounding box and edge length ex5::TriangleMesh mesh(ex5::TriangleMesh::BBox{bb_min, bb_max}, h); // Function to select points within circles (assuming select_union is defined in task2) auto in_circle = [&](const task2::Vec2d& p, task2::Vec2d center, double radius) { return std::sqrt(std::pow(p[0] - center[0], 2) + std::pow(p[1] - center[1], 2)) <= radius; }; // Select and remove vertices inside both inner circles (union) std::unordered_set remove_inner; for (size_t i = 0; i < mesh.getVertices().size(); ++i) { const auto& v = mesh.getVertices()[i]; if (in_circle(v, c1, r) && in_circle(v, c2, r)) { remove_inner.insert(i); } } mesh.remove_vertices(remove_inner); // Select and remove vertices outside both outer circles (union - inverted) std::unordered_set remove_outer; for (size_t i = 0; i < mesh.getVertices().size(); ++i) { const auto& v = mesh.getVertices()[i]; if (!in_circle(v, c1, R) && !in_circle(v, c2, R)) { remove_outer.insert(i); } } mesh.remove_vertices(remove_outer); return mesh; } } // namespace task3