79 lines
3.1 KiB
C++
79 lines
3.1 KiB
C++
/// @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 <cmath> // 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<size_t> 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<size_t> 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
|