110 logical :: initialized = .false.
111 real(kind=
dp) :: box_min(3) = huge(0.0_dp)
112 real(kind=
dp) :: box_max(3) = -huge(0.0_dp)
113 real(kind=
dp) :: center(3) = 0.0_dp
114 real(kind=
dp) :: diameter = huge(0.0_dp)
115 real(kind=
dp) :: surface_area = 0.0_dp
136 generic ::
operator(.lt.) => less
137 generic ::
operator(.gt.) => greater
184 class(*),
intent(in) :: object
185 real(kind=
dp),
intent(in),
optional :: padding
191 call box%init(object%get_min(), object%get_max())
209 call neko_error(
"get_aabb: Unsupported object type")
212 if (
present(padding))
then
213 call box%add_padding(padding)
224 class(
aabb_t),
intent(inout) :: this
225 real(kind=
dp),
intent(in) :: padding
226 real(kind=
dp) :: box_min(3), box_max(3)
228 box_min = this%box_min - padding * (this%diameter)
229 box_max = this%box_max + padding * (this%diameter)
231 call this%init(box_min, box_max)
249 real(kind=
dp) :: box_min(3), box_max(3)
251 box_min = huge(0.0_dp); box_max = -huge(0.0_dp)
253 do i = 1, object%n_points()
255 box_min = min(box_min, pi%x)
256 box_max =
max(box_max, pi%x)
259 call box%init(box_min, box_max)
271 type(
mesh_t),
intent(in) :: object
277 do i = 1, object%nelv
278 temp_box =
get_aabb(object%elements(i))
279 box =
merge(box, temp_box)
299 do i = 1, object%nelv
301 box =
merge(box, temp_box)
321 do i = 1, object%nelv
323 box =
merge(box, temp_box)
336 subroutine aabb_init(this, lower_left_front, upper_right_back)
337 class(
aabb_t),
intent(inout) :: this
338 real(kind=
dp),
dimension(3),
intent(in) :: lower_left_front
339 real(kind=
dp),
dimension(3),
intent(in) :: upper_right_back
341 this%initialized = .true.
342 this%box_min = lower_left_front
343 this%box_max = upper_right_back
344 this%center = (this%box_min + this%box_max) / 2.0_dp
345 this%diameter = norm2(this%box_max - this%box_min)
347 this%surface_area = this%calculate_surface_area()
357 class(
aabb_t),
intent(in) :: this
358 real(kind=
dp),
dimension(3) :: min
365 class(
aabb_t),
intent(in) :: this
366 real(kind=
dp),
dimension(3) ::
max
373 class(
aabb_t),
intent(in) :: this
374 real(kind=
dp) :: width
376 width = this%box_max(1) - this%box_min(1)
381 class(
aabb_t),
intent(in) :: this
382 real(kind=
dp) :: depth
384 depth = this%box_max(2) - this%box_min(2)
389 class(
aabb_t),
intent(in) :: this
390 real(kind=
dp) :: height
392 height = this%box_max(3) - this%box_min(3)
397 class(
aabb_t),
intent(in) :: this
398 real(kind=
dp) :: diameter
400 diameter = this%diameter
405 class(
aabb_t),
intent(in) :: this
406 real(kind=
dp) :: surface_area
408 surface_area = this%surface_area
413 class(
aabb_t),
intent(in) :: this
414 real(kind=
dp),
dimension(3) :: center
421 class(
aabb_t),
intent(in) :: this
422 real(kind=
dp),
dimension(3) :: diagonal
424 diagonal = this%box_max - this%box_min
433 class(
aabb_t),
intent(in) :: this
434 class(
aabb_t),
intent(in) :: other
435 logical :: is_overlapping
437 if (.not. this%initialized .or. .not. other%initialized)
then
439 is_overlapping = .false.
442 is_overlapping = all(this%box_min .le. other%box_max) .and. &
443 all(this%box_max .ge. other%box_min)
450 class(
aabb_t),
intent(in) :: this
451 class(
aabb_t),
intent(in) :: other
452 logical :: is_contained
458 is_contained = all(this%box_min .le. other%box_min) .and. &
459 all(this%box_max .ge. other%box_max)
465 class(
aabb_t),
intent(in) :: this
466 real(kind=
dp),
dimension(3),
intent(in) :: p
467 logical :: is_contained
473 is_contained = all(p .ge. this%box_min) .and. all(p .le. this%box_max)
482 class(
aabb_t),
intent(in) :: box1
483 class(
aabb_t),
intent(in) :: box2
486 real(kind=
dp),
dimension(3) :: box_min, box_max
488 box_min = min(box1%box_min, box2%box_min)
489 box_max =
max(box1%box_max, box2%box_max)
491 call merged%init(box_min, box_max)
496 class(
aabb_t),
intent(in) :: box1
497 class(
aabb_t),
intent(in) :: box2
498 type(
aabb_t) :: intersected
500 real(kind=
dp),
dimension(3) :: box_min, box_max
502 box_min =
max(box1%box_min, box2%box_min)
503 box_max = min(box1%box_max, box2%box_max)
505 call intersected%init(box_min, box_max)
514 class(
aabb_t),
intent(in) :: this
515 real(kind=
dp) :: surface_area
517 surface_area = 2.0 * (&
518 & this%get_width() * this%get_height() &
519 & + this%get_width() * this%get_depth() &
520 & + this%get_height() * this%get_depth() &
530 class(
aabb_t),
intent(in) :: this
531 class(
aabb_t),
intent(in) :: other
535 if (.not. this%initialized .or. .not. other%initialized)
then
540 aabb_less = this%box_min(1) .lt. other%box_min(1)
541 equal = this%box_min(1) .le. other%box_min(1)
544 aabb_less = this%box_min(2) .lt. other%box_min(2)
545 equal = this%box_min(2) .le. other%box_min(2)
548 aabb_less = this%box_min(3) .lt. other%box_min(3)
549 equal = this%box_min(3) .le. other%box_min(3)
552 aabb_less = this%box_max(1) .lt. other%box_max(1)
553 equal = this%box_max(1) .le. other%box_max(1)
556 aabb_less = this%box_max(2) .lt. other%box_max(2)
557 equal = this%box_max(2) .le. other%box_max(2)
560 aabb_less = this%box_max(3) .lt. other%box_max(3)
567 class(
aabb_t),
intent(in) :: this
568 class(
aabb_t),
intent(in) :: other
572 if (.not. this%initialized .or. .not. other%initialized)
then
578 equal = this%box_min(1) .ge. other%box_min(1)
582 equal = this%box_min(2) .ge. other%box_min(2)
586 equal = this%box_min(3) .ge. other%box_min(3)
590 equal = this%box_max(1) .ge. other%box_max(1)
594 equal = this%box_max(2) .ge. other%box_max(2)
Axis Aligned Bounding Box (aabb) implementation in Fortran.
pure real(kind=dp) function, dimension(3) aabb_get_max(this)
Get the maximum point of the aabb.
pure real(kind=dp) function aabb_get_surface_area(this)
Get the surface area of the aabb.
pure real(kind=dp) function aabb_get_diameter(this)
Get the diameter length of the aabb.
subroutine add_padding(this, padding)
Add padding to the aabb.
logical function aabb_contains_point(this, p)
Check if this aabb contains a point.
subroutine aabb_init(this, lower_left_front, upper_right_back)
Initialize the aabb.
type(aabb_t) function get_aabb_tri_mesh(object)
Get the aabb of a triangular mesh.
logical function aabb_overlaps(this, other)
Check if two aabbs are overlapping.
type(aabb_t) function get_aabb_mesh(object)
Get the aabb of a mesh.
type(aabb_t) function intersection_aabb(box1, box2)
Get the intersection of two aabbs.
pure real(kind=dp) function aabb_get_height(this)
Get the height of the aabb. Also known as the z-axis length.
pure logical function aabb_greater(this, other)
Greater than comparison operator.
type(aabb_t) function, public get_aabb(object, padding)
Construct the aabb of a predefined object.
logical function aabb_contains_other(this, other)
Check if this aabb contains another aabb.
pure real(kind=dp) function calculate_surface_area(this)
Calculate the surface area of the aabb.
pure logical function aabb_less(this, other)
Less than comparison operator.
type(aabb_t) function get_aabb_element(object)
Get the aabb of an arbitrary element.
type(aabb_t) function get_aabb_tet_mesh(object)
Get the aabb of a tetrahedral mesh.
pure real(kind=dp) function, dimension(3) aabb_get_center(this)
Get the center of the aabb.
pure real(kind=dp) function aabb_get_width(this)
Get the width of the aabb. Also known as the x-axis length.
pure real(kind=dp) function, dimension(3) aabb_get_diagonal(this)
Get the diagonal of the aabb.
type(aabb_t) function merge_aabb(box1, box2)
Merge two aabbs.
pure real(kind=dp) function aabb_get_depth(this)
Get the depth of the aabb. Also known as the y-axis length.
pure real(kind=dp) function, dimension(3) aabb_get_min(this)
Get the minimum point of the aabb.
Defines a hexahedron element.
integer, parameter, public dp
Defines a quadrilateral element.
Defines a tetrahedral mesh.
Defines a tetrahedral element.
Defines a triangular surface mesh.
Defines a triangular element.
Axis Aligned Bounding Box (aabb) data structure.
Base type for an element.
A point in with coordinates .