/// @file /// @brief Task2: member function definitions/implementations #include "task2.hpp" // task2::Vec2, task2::BBox, task2::Circle, task2::Triangle #include "task2.misc.hpp" // task2::operator<<, task2::isnan, task2::isclose #include "modules/iue-num/numerics.hpp" // iue::num::isclose /// @todo Include standard library headers as needed namespace task2 { /// ==================================== Bounding Box ================================================= /// @todo Implement the missing member functions for bounding box as declared and specified in task2.hpp /// @todo implement member function 'BBox::scale' BBox BBox::scale(const Vec2d& org, double s) const { BBox scaled_box = *this; scaled_box.min[0] = org[0] + s * (min[0] - org[0]); scaled_box.min[1] = org[1] + s * (min[1] - org[1]); scaled_box.max[0] = org[0] + s * (max[0] - org[0]); scaled_box.max[1] = org[1] + s * (max[1] - org[1]); return scaled_box; } /// @todo implement member function 'BBox::translate' BBox BBox::translate(const Vec2d& offset) const { BBox translated_box = *this; translated_box.min[0] += offset[0]; translated_box.min[1] += offset[1]; translated_box.max[0] += offset[0]; translated_box.max[1] += offset[1]; return translated_box; } /// @todo implement member function 'BBox::check_invariants' bool BBox::check_invariants() const { if (std::isnan(min[0]) || std::isnan(min[1]) || std::isnan(max[0]) || std::isnan(max[1])) { return false; } if (min[0] > max[0] || min[1] > max[1]) { return false; } if (iue::num::isclose(min[0], max[0]) && iue::num::isclose(min[1], max[1])) { return false; } return true; } /// ==================================== Circle ================================================ /// @todo Implement the missing member functions for Circle as declared and specified in task2.hpp /// @todo implement member function 'Circle::bbox' BBox Circle::bbox() const { BBox box = {{c[0] - r, c[1] - r}, {c[0] + r, c[1] + r}}; return box; } /// @todo implement member function 'Circle::scale' Circle Circle::scale(const Vec2d& org, double s) const { Circle scaled_circle = *this; scaled_circle.c[0] = org[0] + s * (c[0] - org[0]); scaled_circle.c[1] = org[1] + s * (c[1] - org[1]); scaled_circle.r *= s; return scaled_circle; } /// @todo implement member function 'Circle::rotate' Circle Circle::rotate(const Vec2d& org, double angle) const { Circle rotated_circle = *this; double x = c[0] - org[0]; double y = c[1] - org[1]; rotated_circle.c[0] = org[0] + x * cos(angle) - y * sin(angle); rotated_circle.c[1] = org[1] + x * sin(angle) + y * cos(angle); return rotated_circle; } /// @todo implement member function 'Circle::translate' Circle Circle::translate(const Vec2d& offset) const { Circle translated_circle = *this; translated_circle.c[0] += offset[0]; translated_circle.c[1] += offset[1]; return translated_circle; } /// @todo implement member function 'Circle::check_invariants' bool Circle::check_invariants() const { if (std::isnan(c[0]) || std::isnan(c[1]) || std::isnan(r)) { return false; } if (r < 0) { return false; } return true; } /// ==================================== Triangle ================================================ /// @todo Implement the missing member functions for Triangle as declared and specified in task2.hpp /// @todo implement member function 'Triangle::bbox' BBox Triangle::bbox() const { BBox box = {{abc[0][0], abc[0][1]}, {abc[0][0], abc[0][1]}}; for (int i = 1; i < 3; i++) { if (abc[i][0] < box.min[0]) { box.min[0] = abc[i][0]; } if (abc[i][0] > box.max[0]) { box.max[0] = abc[i][0]; } if (abc[i][1] < box.min[1]) { box.min[1] = abc[i][1]; } if (abc[i][1] > box.max[1]) { box.max[1] = abc[i][1]; } } return box; } /// @todo implement member function 'Triangle::scale' Triangle Triangle::scale(const Vec2d& org, double s) const { Triangle scaled_triangle = *this; for (int i = 0; i < 3; i++) { scaled_triangle.abc[i][0] = org[0] + s * (abc[i][0] - org[0]); scaled_triangle.abc[i][1] = org[1] + s * (abc[i][1] - org[1]); } return scaled_triangle; } /// @todo implement member function 'Triangle::rotate' Triangle Triangle::rotate(const Vec2d& org, double angle) const { Triangle rotated_triangle = *this; for (int i = 0; i < 3; i++) { double x = abc[i][0] - org[0]; double y = abc[i][1] - org[1]; rotated_triangle.abc[i][0] = org[0] + x * cos(angle) - y * sin(angle); rotated_triangle.abc[i][1] = org[1] + x * sin(angle) + y * cos(angle); } return rotated_triangle; } /// @todo implement member function 'Triangle::translate' Triangle Triangle::translate(const Vec2d& offset) const { Triangle translated_triangle = *this; for (int i = 0; i < 3; i++) { translated_triangle.abc[i][0] += offset[0]; translated_triangle.abc[i][1] += offset[1]; } return translated_triangle; } /// @todo implement member function 'Triangle::bbox' bool Triangle::check_invariants() const { if (std::isnan(abc[0][0]) || std::isnan(abc[0][1]) || std::isnan(abc[1][0]) || std::isnan(abc[1][1]) || std::isnan(abc[2][0]) || std::isnan(abc[2][1])) { return false; } if (iue::num::isclose(abc[0][0], abc[1][0]) && iue::num::isclose(abc[0][1], abc[1][1])) { return false; } if (iue::num::isclose(abc[0][0], abc[2][0]) && iue::num::isclose(abc[0][1], abc[2][1])) { return false; } if (iue::num::isclose(abc[1][0], abc[2][0]) && iue::num::isclose(abc[1][1], abc[2][1])) { return false; } return true; } } // namespace task2