diff --git a/kratos/geometries/bounding_box.h b/kratos/geometries/bounding_box.h index 468a1a2a43a5..1a5fc7ec0b39 100644 --- a/kratos/geometries/bounding_box.h +++ b/kratos/geometries/bounding_box.h @@ -17,7 +17,7 @@ // External includes // Project includes -#include "includes/define.h" +#include "containers/array_1d.h" namespace Kratos { @@ -69,7 +69,7 @@ class BoundingBox /// Construction with container of points. template - BoundingBox(TIteratorType const& itPointsBegin, TIteratorType const& itPointsEnd) + BoundingBox(TIteratorType const& itPointsBegin, TIteratorType const& itPointsEnd) { Set(itPointsBegin, itPointsEnd); } @@ -167,6 +167,25 @@ class BoundingBox } } + /** + * @brief Checks if a point is inside the bounding box with tolerance. + * @details This function checks if a given point is inside the bounding box defined by the minimum and maximum points. It returns true if the point is inside the bounding box within the given tolerance, and false otherwise. + * @param rPoint The point to be checked. + * @param Tolerance A tolerance value to allow for slight inaccuracies (default is std::numeric_limits::epsilon()). + * @return True if the point is inside the bounding box within the given tolerance, false otherwise. + */ + bool IsInside( + const array_1d& rPoint, + const double Tolerance = std::numeric_limits::epsilon() + ) const + { + for (unsigned int i = 0; i < Dimension; i++) { + if (rPoint[i] < GetMinPoint()[i] - Tolerance || rPoint[i] > GetMaxPoint()[i] + Tolerance) + return false; + } + return true; + } + ///@} ///@name Access ///@{ diff --git a/kratos/python/add_bounding_box_to_python.cpp b/kratos/python/add_bounding_box_to_python.cpp index 47408ee8d8f4..6d91d8f2ee1c 100644 --- a/kratos/python/add_bounding_box_to_python.cpp +++ b/kratos/python/add_bounding_box_to_python.cpp @@ -43,6 +43,9 @@ void AddBoundingBoxToPython(pybind11::module& m) .def("Extend", [](BoundingBoxType& rBoundingBox, const NodesContainerType& rNodes){ rBoundingBox.Extend(rNodes.begin(), rNodes.end()); }) + .def("IsInside", [](BoundingBoxType& rBoundingBox, const Point& rPoint){ + return rBoundingBox.IsInside(rPoint); + }) .def("GetMinPoint", [](BoundingBoxType& rBoundingBox){ return rBoundingBox.GetMinPoint(); }) diff --git a/kratos/tests/cpp_tests/geometries/test_bounding_box.cpp b/kratos/tests/cpp_tests/geometries/test_bounding_box.cpp index 48b6e0b6e952..f5b939b35edb 100644 --- a/kratos/tests/cpp_tests/geometries/test_bounding_box.cpp +++ b/kratos/tests/cpp_tests/geometries/test_bounding_box.cpp @@ -4,8 +4,8 @@ // _|\_\_| \__,_|\__|\___/ ____/ // Multi-Physics // -// License: BSD License -// Kratos default license: kratos/license.txt +// License: BSD License +// Kratos default license: kratos/license.txt // // Main authors: Aditya Ghantasala // Vicente Mataix Ferrandiz @@ -21,116 +21,129 @@ #include "geometries/bounding_box.h" #include "geometries/point.h" -namespace Kratos { -namespace Testing { - - - /** Checks BoundingBox creation with min max point - */ - KRATOS_TEST_CASE_IN_SUITE(BoundingBoxMinMaxConstruction, KratosCoreGeometriesFastSuite) { - constexpr double tolerance = 1e-12; - BoundingBox bounding_box({0, .1, .3}, {2.1, 3.4, 5.6}); - - - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0], 0.00, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1], 0.10, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2], 0.30, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 2.10, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 3.40, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 5.60, tolerance); - } - - - /** Checks BoundingBox copy and assingment - */ - KRATOS_TEST_CASE_IN_SUITE(BoundingCopyAndAssignment, KratosCoreGeometriesFastSuite) { - constexpr double tolerance = 1e-12; - BoundingBox bounding_box({0, .1, .3}, {2.1, 3.4, 5.6}); - - BoundingBox copied_box(bounding_box); - BoundingBox assigned_box({0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}); - - assigned_box = copied_box; - - - KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[0], 0.00, tolerance); - KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[1], 0.10, tolerance); - KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[2], 0.30, tolerance); - KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[0], 2.10, tolerance); - KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[1], 3.40, tolerance); - KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[2], 5.60, tolerance); - } - - /** Checks BoundingBox creation with iterator of points - */ - KRATOS_TEST_CASE_IN_SUITE(BoundingPointsConstruction, KratosCoreGeometriesFastSuite) { - constexpr double tolerance = 1e-12; - - std::vector points; - points.push_back(Point{0.0, 0.4, -0.3}); - points.push_back(Point{0.9, -0.3, 0.1}); - points.push_back(Point{-0.2, 0.4, 0.3}); - points.push_back(Point{0.0, 0.8, -0.5}); - - BoundingBox bounding_box(points.begin(), points.end()); - - - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); - } - - /** Checks BoundingBox set method - */ - KRATOS_TEST_CASE_IN_SUITE(BoundingBoxSet, KratosCoreGeometriesFastSuite) { - constexpr double tolerance = 1e-12; - - std::vector points; - points.push_back(Point{0.0, 0.4, -0.3}); - points.push_back(Point{0.9, -0.3, 0.1}); - points.push_back(Point{-0.2, 0.4, 0.3}); - points.push_back(Point{0.0, 0.8, -0.5}); - - - BoundingBox bounding_box; - - bounding_box.Set(points.begin(), points.end()); - - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); - } - - /** Checks BoundingBox set method - */ - KRATOS_TEST_CASE_IN_SUITE(BoundingSet, KratosCoreGeometriesFastSuite) { - constexpr double tolerance = 1e-12; - - std::vector points; - points.push_back(Point{0.0, 0.4, -0.3}); - points.push_back(Point{0.9, -0.3, 0.1}); - - BoundingBox bounding_box(points.begin(), points.end()); - - points[0] = Point{-0.2, 0.4, 0.3}; - points[1] = Point{0.0, 0.8, -0.5}; - - bounding_box.Extend(points.begin(), points.end()); - - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); - KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); - } - - -} // namespace Testing. -} // namespace Kratos. +namespace Kratos::Testing +{ + +/** Checks BoundingBox creation with min max point +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingBoxMinMaxConstruction, KratosCoreGeometriesFastSuite) +{ + constexpr double tolerance = 1e-12; + BoundingBox bounding_box({0, .1, .3}, {2.1, 3.4, 5.6}); + + + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0], 0.00, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1], 0.10, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2], 0.30, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 2.10, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 3.40, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 5.60, tolerance); +} + + +/** Checks BoundingBox copy and assingment +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingCopyAndAssignment, KratosCoreGeometriesFastSuite) +{ + constexpr double tolerance = 1e-12; + BoundingBox bounding_box({0, .1, .3}, {2.1, 3.4, 5.6}); + + BoundingBox copied_box(bounding_box); + BoundingBox assigned_box({0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}); + + assigned_box = copied_box; + + + KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[0], 0.00, tolerance); + KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[1], 0.10, tolerance); + KRATOS_EXPECT_NEAR(assigned_box.GetMinPoint()[2], 0.30, tolerance); + KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[0], 2.10, tolerance); + KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[1], 3.40, tolerance); + KRATOS_EXPECT_NEAR(assigned_box.GetMaxPoint()[2], 5.60, tolerance); +} + +/** Checks BoundingBox creation with iterator of points +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingPointsConstruction, KratosCoreGeometriesFastSuite) +{ + constexpr double tolerance = 1e-12; + + std::vector points; + points.push_back(Point{0.0, 0.4, -0.3}); + points.push_back(Point{0.9, -0.3, 0.1}); + points.push_back(Point{-0.2, 0.4, 0.3}); + points.push_back(Point{0.0, 0.8, -0.5}); + + BoundingBox bounding_box(points.begin(), points.end()); + + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); +} + +/** Checks BoundingBox set method +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingBoxSet, KratosCoreGeometriesFastSuite) +{ + constexpr double tolerance = 1e-12; + + std::vector points; + points.push_back(Point{0.0, 0.4, -0.3}); + points.push_back(Point{0.9, -0.3, 0.1}); + points.push_back(Point{-0.2, 0.4, 0.3}); + points.push_back(Point{0.0, 0.8, -0.5}); + + BoundingBox bounding_box; + + bounding_box.Set(points.begin(), points.end()); + + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); +} + +/** Checks BoundingBox extend method +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingBoxExtend, KratosCoreGeometriesFastSuite) +{ + constexpr double tolerance = 1e-12; + + std::vector points; + points.push_back(Point{0.0, 0.4, -0.3}); + points.push_back(Point{0.9, -0.3, 0.1}); + + BoundingBox bounding_box(points.begin(), points.end()); + + points[0] = Point{-0.2, 0.4, 0.3}; + points[1] = Point{0.0, 0.8, -0.5}; + + bounding_box.Extend(points.begin(), points.end()); + + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[0],-0.20, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[1],-0.30, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMinPoint()[2],-0.50, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[0], 0.90, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[1], 0.80, tolerance); + KRATOS_EXPECT_NEAR(bounding_box.GetMaxPoint()[2], 0.30, tolerance); +} + +/** Checks BoundingBox IsInside method +*/ +KRATOS_TEST_CASE_IN_SUITE(BoundingBoxIsInside, KratosCoreGeometriesFastSuite) +{ + BoundingBox bounding_box({0.0, 0.0, 0.0}, {1.0, 1.0, 1.0}); + + Point point_inside{0.5, 0.5, 0.5}; + Point point_outside{1.5, 0.5, 0.5}; + + KRATOS_CHECK(bounding_box.IsInside(point_inside)); + KRATOS_CHECK_IS_FALSE(bounding_box.IsInside(point_outside)); +} + +} // namespace Kratos::Testing. diff --git a/kratos/tests/test_bounding_box.py b/kratos/tests/test_bounding_box.py index 3f26c9efe672..52eb0224e048 100644 --- a/kratos/tests/test_bounding_box.py +++ b/kratos/tests/test_bounding_box.py @@ -50,6 +50,15 @@ def test_BoundingBoxExtendWithDouble(self): bb.Extend(1.0) self._CheckBoundingBoxPoints(bb) + def test_BoundingBoxIsInside(self): + min_point = KM.Point(-1.0, -5.0, 0.0) + max_point = KM.Point( 1.0, 10.0, 80.0) + bb = KM.BoundingBox(min_point, max_point) + point_inside = KM.Point(0.0, 0.0, 0.0) + self.assertTrue(bb.IsInside(point_inside)) + point_outside = KM.Point(0.0, 0.0, 100.0) + self.assertFalse(bb.IsInside(point_outside)) + def _CheckBoundingBoxPoints(self, bounding_box): min_point, max_point = bounding_box.GetPoints()