@@ -172,15 +172,24 @@ def corners(self):
172172 corners .append (corner )
173173 return corners
174174
175- def overlaps (self , aabb ):
175+ def overlaps (self , aabb , closed = False ):
176176 """Determine if two AABBs overlap
177177
178178 Args:
179179 aabb (AABB): The AABB to check for overlap
180+ closed (bool): Flag for closed overlap between AABBs. For the case
181+ where one box is [-1, 0] and the other is [0, 0], the two boxes
182+ are interecting if closed is set to True and they are not
183+ intersecting if closed is set to False.
180184
181185 Returns:
182186 bool: Flag set to true if the two AABBs overlap
183187 """
188+ if closed :
189+ return self ._overlaps_closed (aabb )
190+ return self ._overlaps_open (aabb )
191+
192+ def _overlaps_open (self , aabb ):
184193 if (self .limits is None ) or (aabb .limits is None ):
185194 return False
186195
@@ -191,6 +200,19 @@ def overlaps(self, aabb):
191200 return False
192201 return True
193202
203+ def _overlaps_closed (self , aabb ):
204+ if (self .limits is None ) or (aabb .limits is None ):
205+ return False
206+
207+ for (min1 , max1 ), (min2 , max2 ) in zip (self .limits , aabb .limits ):
208+ if min1 > max2 :
209+ return False
210+ if min2 > max1 :
211+ return False
212+ return True
213+
214+
215+
194216 def overlap_volume (self , aabb ):
195217 r"""Determine volume of overlap between AABBs
196218
@@ -425,7 +447,7 @@ def add(self, aabb, value=None, method='volume'):
425447 self .right .add (aabb , value )
426448 self .aabb = AABB .merge (self .left .aabb , self .right .aabb )
427449
428- def does_overlap (self , aabb , method = 'DFS' ):
450+ def does_overlap (self , aabb , method = 'DFS' , closed = False ):
429451 """Check for overlap
430452
431453 This function checks if the limits overlap any leaf nodes in the tree.
@@ -441,13 +463,17 @@ def does_overlap(self, aabb, method='DFS'):
441463 method (str): {'DFS'|'BFS'} Method for traversing the tree.
442464 Setting 'DFS' performs a depth-first search and 'BFS' performs
443465 a breadth-first search. Defaults to 'DFS'.
466+ closed (bool): Option to specify closed or open box intersection.
467+ If open, there must be a non-zero amount of overlap. If closed,
468+ boxes can be touching.
444469
445470 Returns:
446471 bool: True if overlaps with a leaf node of tree.
447472 """
448- return len (_overlap_pairs (self , aabb , method , halt = True )) > 0
449473
450- def overlap_aabbs (self , aabb , method = 'DFS' ):
474+ return len (_overlap_pairs (self , aabb , method , True , closed )) > 0
475+
476+ def overlap_aabbs (self , aabb , method = 'DFS' , closed = False ):
451477 """Get overlapping AABBs
452478
453479 This function gets each overlapping AABB.
@@ -462,17 +488,20 @@ def overlap_aabbs(self, aabb, method='DFS'):
462488 method (str): {'DFS'|'BFS'} Method for traversing the tree.
463489 Setting 'DFS' performs a depth-first search and 'BFS' performs
464490 a breadth-first search. Defaults to 'DFS'.
491+ closed (bool): Option to specify closed or open box intersection.
492+ If open, there must be a non-zero amount of overlap. If closed,
493+ boxes can be touching.
465494
466495 Returns:
467496 list: AABB objects in AABBTree that overlap with the input.
468497 """
469- pairs = _overlap_pairs (self , aabb , method )
498+ pairs = _overlap_pairs (self , aabb , method , closed = closed )
470499 if len (pairs ) == 0 :
471500 return []
472501 boxes , _ = zip (* pairs )
473502 return list (boxes )
474503
475- def overlap_values (self , aabb , method = 'DFS' ):
504+ def overlap_values (self , aabb , method = 'DFS' , closed = False ):
476505 """Get values of overlapping AABBs
477506
478507 This function gets the value field of each overlapping AABB.
@@ -487,11 +516,14 @@ def overlap_values(self, aabb, method='DFS'):
487516 method (str): {'DFS'|'BFS'} Method for traversing the tree.
488517 Setting 'DFS' performs a depth-first search and 'BFS' performs
489518 a breadth-first search. Defaults to 'DFS'.
519+ closed (bool): Option to specify closed or open box intersection.
520+ If open, there must be a non-zero amount of overlap. If closed,
521+ boxes can be touching.
490522
491523 Returns:
492524 list: Value fields of each node that overlaps.
493525 """
494- pairs = _overlap_pairs (self , aabb , method )
526+ pairs = _overlap_pairs (self , aabb , method , closed = closed )
495527 if len (pairs ) == 0 :
496528 return []
497529 _ , values = zip (* pairs )
@@ -505,7 +537,7 @@ def _merge(lims1, lims2):
505537 return (lower , upper )
506538
507539
508- def _overlap_pairs (in_tree , aabb , method = 'DFS' , halt = False ):
540+ def _overlap_pairs (in_tree , aabb , method = 'DFS' , halt = False , closed = False ):
509541 """Get overlapping AABBs and values in (AABB, value) pairs
510542
511543 *New in version 2.6.0*
@@ -518,8 +550,9 @@ def _overlap_pairs(in_tree, aabb, method='DFS', halt=False):
518550 method (str): {'DFS'|'BFS'} Method for traversing the tree.
519551 Setting 'DFS' performs a depth-first search and 'BFS' performs
520552 a breadth-first search. Defaults to 'DFS'.
521- halt (bool): Return the list immediately once a pair has been
553+ halt (bool): Return the list immediately once a pair has been
522554 added.
555+ closed (bool): Check for closed box intersection. Defaults to False.
523556
524557 Returns:
525558 list: (AABB, value) pairs in AABBTree that overlap with the input.
@@ -530,10 +563,10 @@ def _overlap_pairs(in_tree, aabb, method='DFS', halt=False):
530563 tree = aabb
531564
532565 if method == 'DFS' :
533- pairs = _overlap_dfs (in_tree , tree , halt )
566+ pairs = _overlap_dfs (in_tree , tree , halt , closed )
534567
535568 elif method == 'BFS' :
536- pairs = _overlap_bfs (in_tree , tree , halt )
569+ pairs = _overlap_bfs (in_tree , tree , halt , closed )
537570 else :
538571 e_str = "method should be 'DFS' or 'BFS', not " + str (method )
539572 raise ValueError (e_str )
@@ -543,7 +576,7 @@ def _overlap_pairs(in_tree, aabb, method='DFS', halt=False):
543576 return _unique_pairs (pairs )
544577
545578
546- def _overlap_dfs (in_tree , tree , halt ):
579+ def _overlap_dfs (in_tree , tree , halt , closed ):
547580 pairs = []
548581
549582 if in_tree .is_leaf :
@@ -556,7 +589,7 @@ def _overlap_dfs(in_tree, tree, halt):
556589 else :
557590 tree_branches = [tree .left , tree .right ]
558591
559- if not in_tree .aabb .overlaps (tree .aabb ):
592+ if not in_tree .aabb .overlaps (tree .aabb , closed ):
560593 return pairs
561594
562595 if in_tree .is_leaf and tree .is_leaf :
@@ -565,20 +598,20 @@ def _overlap_dfs(in_tree, tree, halt):
565598
566599 for in_branch in in_branches :
567600 for tree_branch in tree_branches :
568- o_pairs = _overlap_dfs (in_branch , tree_branch , halt )
601+ o_pairs = _overlap_dfs (in_branch , tree_branch , halt , closed )
569602 pairs .extend (o_pairs )
570603 if halt and len (pairs ) > 0 :
571604 return pairs
572605 return pairs
573606
574607
575- def _overlap_bfs (in_tree , tree , halt ):
608+ def _overlap_bfs (in_tree , tree , halt , closed ):
576609 pairs = []
577610 queue = deque ()
578611 queue .append ((in_tree , tree ))
579612 while len (queue ) > 0 :
580613 s_node , t_node = queue .popleft ()
581- if s_node .aabb .overlaps (t_node .aabb ):
614+ if s_node .aabb .overlaps (t_node .aabb , closed ):
582615 if s_node .is_leaf and t_node .is_leaf :
583616 pairs .append ((s_node .aabb , s_node .value ))
584617 if halt :
0 commit comments