Skip to content

Commit

Permalink
Merge pull request #12600 from KratosMultiphysics/core/geometry/is-in…
Browse files Browse the repository at this point in the history
…side-bb

[Core] Add `IsInside` method to `BoundingBox` class
  • Loading branch information
loumalouomega authored Oct 9, 2024
2 parents 23c3728 + e2bfe4f commit a6e214f
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 117 deletions.
23 changes: 21 additions & 2 deletions kratos/geometries/bounding_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// External includes

// Project includes
#include "includes/define.h"
#include "containers/array_1d.h"

namespace Kratos
{
Expand Down Expand Up @@ -69,7 +69,7 @@ class BoundingBox

/// Construction with container of points.
template<typename TIteratorType>
BoundingBox(TIteratorType const& itPointsBegin, TIteratorType const& itPointsEnd)
BoundingBox(TIteratorType const& itPointsBegin, TIteratorType const& itPointsEnd)
{
Set(itPointsBegin, itPointsEnd);
}
Expand Down Expand Up @@ -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<double>::epsilon()).
* @return True if the point is inside the bounding box within the given tolerance, false otherwise.
*/
bool IsInside(
const array_1d<double, 3>& rPoint,
const double Tolerance = std::numeric_limits<double>::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
///@{
Expand Down
3 changes: 3 additions & 0 deletions kratos/python/add_bounding_box_to_python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
})
Expand Down
243 changes: 128 additions & 115 deletions kratos/tests/cpp_tests/geometries/test_bounding_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<Point> 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<Point> bounding_box({0, .1, .3}, {2.1, 3.4, 5.6});

BoundingBox<Point> copied_box(bounding_box);
BoundingBox<Point> 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<Point> 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<Point> 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<Point> 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<Point> 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<Point> points;
points.push_back(Point{0.0, 0.4, -0.3});
points.push_back(Point{0.9, -0.3, 0.1});

BoundingBox<Point> 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<Point> 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<Point> bounding_box({0, .1, .3}, {2.1, 3.4, 5.6});

BoundingBox<Point> copied_box(bounding_box);
BoundingBox<Point> 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<Point> 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<Point> 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<Point> 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<Point> 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<Point> points;
points.push_back(Point{0.0, 0.4, -0.3});
points.push_back(Point{0.9, -0.3, 0.1});

BoundingBox<Point> 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<Point> 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.
9 changes: 9 additions & 0 deletions kratos/tests/test_bounding_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down

0 comments on commit a6e214f

Please sign in to comment.