From e99f3db698c3b411fc07d602bb353f40f263f587 Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Thu, 19 Dec 2024 19:16:02 -0800 Subject: [PATCH] fix(bounding): Add generic check for overlapping bounding box --- ladybug_geometry/bounding.py | 67 +++++++++++++++++++++++++ ladybug_geometry/geometry2d/polygon.py | 6 ++- ladybug_geometry/geometry3d/polyface.py | 9 ++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/ladybug_geometry/bounding.py b/ladybug_geometry/bounding.py index e8fe5734..75dca868 100644 --- a/ladybug_geometry/bounding.py +++ b/ladybug_geometry/bounding.py @@ -204,3 +204,70 @@ def bounding_box_extents(geometries, axis_angle=0): yy = bounding_domain_y(geometries) zz = bounding_domain_z_2d_safe(geometries) return xx[1] - xx[0], yy[1] - yy[0], zz[1] - zz[0] + + +def overlapping_bounding_rect(geometry_1, geometry_2, distance): + """Check if the bounding rectangles of two geometries overlap within a tolerance. + + Args: + geometry_1: The first geometry to check. + geometry_2: The second geometry to check. + distance: The maximum distance at which the geometries are + considered overlapping. + + Return: + True if the geometries overlap. False if they do not. + """ + # Bounding box check using the Separating Axis Theorem + geo1_width = geometry_1.max.x - geometry_1.min.x + geo2_width = geometry_2.max.x - geometry_2.min.x + dist_btwn_x = abs(geometry_1.center.x - geometry_2.center.x) + x_gap_btwn_box = dist_btwn_x - (0.5 * geo1_width) - (0.5 * geo2_width) + if x_gap_btwn_box > distance: + return False # overlap impossible + + geo1_depth = geometry_1.max.y - geometry_1.min.y + geo2_depth = geometry_2.max.y - geometry_2.min.y + dist_btwn_y = abs(geometry_1.center.y - geometry_2.center.y) + y_gap_btwn_box = dist_btwn_y - (0.5 * geo1_depth) - (0.5 * geo2_depth) + if y_gap_btwn_box > distance: + return False # overlap impossible + + return True # overlap exists + + +def overlapping_bounding_boxes(geometry_1, geometry_2, distance): + """Check if the bounding boxes around two geometries overlap within a distance. + + Args: + geometry_1: The first geometry to check. + geometry_2: The second geometry to check. + distance: The maximum distance at which the geometries are + considered overlapping. + + Return: + True if the geometries overlap. False if they do not. + """ + # Bounding box check using the Separating Axis Theorem + geo1_width = geometry_1.max.x - geometry_1.min.x + geo2_width = geometry_2.max.x - geometry_2.min.x + dist_btwn_x = abs(geometry_1.center.x - geometry_2.center.x) + x_gap_btwn_box = dist_btwn_x - (0.5 * geo1_width) - (0.5 * geo2_width) + if x_gap_btwn_box > distance: + return False # overlap impossible + + geo1_depth = geometry_1.max.y - geometry_1.min.y + geo2_depth = geometry_2.max.y - geometry_2.min.y + dist_btwn_y = abs(geometry_1.center.y - geometry_2.center.y) + y_gap_btwn_box = dist_btwn_y - (0.5 * geo1_depth) - (0.5 * geo2_depth) + if y_gap_btwn_box > distance: + return False # overlap impossible + + geo1_height = geometry_1.max.z - geometry_1.min.z + geo2_height = geometry_2.max.z - geometry_2.min.z + dist_btwn_z = abs(geometry_1.center.z - geometry_2.center.z) + z_gap_btwn_box = dist_btwn_z - (0.5 * geo1_height) - (0.5 * geo2_height) + if z_gap_btwn_box > distance: + return False # overlap impossible + + return True # overlap exists diff --git a/ladybug_geometry/geometry2d/polygon.py b/ladybug_geometry/geometry2d/polygon.py index 1b0d14d3..4ce6b473 100644 --- a/ladybug_geometry/geometry2d/polygon.py +++ b/ladybug_geometry/geometry2d/polygon.py @@ -1717,14 +1717,16 @@ def overlapping_bounding_rect(polygon1, polygon2, tolerance): polygon2_width = polygon2.max.x - polygon2.min.x dist_btwn_x = abs(polygon1.center.x - polygon2.center.x) x_gap_btwn_rect = dist_btwn_x - (0.5 * polygon1_width) - (0.5 * polygon2_width) + if x_gap_btwn_rect > tolerance: + return False polygon1_height = polygon1.max.y - polygon1.min.y polygon2_height = polygon2.max.y - polygon2.min.y dist_btwn_y = abs(polygon1.center.y - polygon2.center.y) y_gap_btwn_rect = dist_btwn_y - (0.5 * polygon1_height) - (0.5 * polygon2_height) + if y_gap_btwn_rect > tolerance: + return False # overlap impossible - if x_gap_btwn_rect > tolerance or y_gap_btwn_rect > tolerance: - return False # no overlap return True # overlap exists @staticmethod diff --git a/ladybug_geometry/geometry3d/polyface.py b/ladybug_geometry/geometry3d/polyface.py index b7ddfdb7..e885b149 100644 --- a/ladybug_geometry/geometry3d/polyface.py +++ b/ladybug_geometry/geometry3d/polyface.py @@ -771,20 +771,23 @@ def overlapping_bounding_boxes(polyface1, polyface2, tolerance): polyf2_width = polyface2.max.x - polyface2.min.x dist_btwn_x = abs(polyface1.center.x - polyface2.center.x) x_gap_btwn_box = dist_btwn_x - (0.5 * polyf1_width) - (0.5 * polyf2_width) + if x_gap_btwn_box > tolerance: + return False # overlap impossible polyf1_depth = polyface1.max.y - polyface1.min.y polyf2_depth = polyface2.max.y - polyface2.min.y dist_btwn_y = abs(polyface1.center.y - polyface2.center.y) y_gap_btwn_box = dist_btwn_y - (0.5 * polyf1_depth) - (0.5 * polyf2_depth) + if y_gap_btwn_box > tolerance: + return False # overlap impossible polyf1_height = polyface1.max.z - polyface1.min.z polyf2_height = polyface2.max.z - polyface2.min.z dist_btwn_z = abs(polyface1.center.z - polyface2.center.z) z_gap_btwn_box = dist_btwn_z - (0.5 * polyf1_height) - (0.5 * polyf2_height) - - if x_gap_btwn_box > tolerance or y_gap_btwn_box > tolerance or \ - z_gap_btwn_box > tolerance: + if z_gap_btwn_box > tolerance: return False # no overlap + return True # overlap exists @staticmethod