@@ -172,15 +172,24 @@ def corners(self):
172
172
corners .append (corner )
173
173
return corners
174
174
175
- def overlaps (self , aabb ):
175
+ def overlaps (self , aabb , closed = False ):
176
176
"""Determine if two AABBs overlap
177
177
178
178
Args:
179
179
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.
180
184
181
185
Returns:
182
186
bool: Flag set to true if the two AABBs overlap
183
187
"""
188
+ if closed :
189
+ return self ._overlaps_closed (aabb )
190
+ return self ._overlaps_open (aabb )
191
+
192
+ def _overlaps_open (self , aabb ):
184
193
if (self .limits is None ) or (aabb .limits is None ):
185
194
return False
186
195
@@ -191,6 +200,19 @@ def overlaps(self, aabb):
191
200
return False
192
201
return True
193
202
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
+
194
216
def overlap_volume (self , aabb ):
195
217
r"""Determine volume of overlap between AABBs
196
218
@@ -425,7 +447,7 @@ def add(self, aabb, value=None, method='volume'):
425
447
self .right .add (aabb , value )
426
448
self .aabb = AABB .merge (self .left .aabb , self .right .aabb )
427
449
428
- def does_overlap (self , aabb , method = 'DFS' ):
450
+ def does_overlap (self , aabb , method = 'DFS' , closed = False ):
429
451
"""Check for overlap
430
452
431
453
This function checks if the limits overlap any leaf nodes in the tree.
@@ -441,13 +463,17 @@ def does_overlap(self, aabb, method='DFS'):
441
463
method (str): {'DFS'|'BFS'} Method for traversing the tree.
442
464
Setting 'DFS' performs a depth-first search and 'BFS' performs
443
465
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.
444
469
445
470
Returns:
446
471
bool: True if overlaps with a leaf node of tree.
447
472
"""
448
- return len (_overlap_pairs (self , aabb , method , halt = True )) > 0
449
473
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 ):
451
477
"""Get overlapping AABBs
452
478
453
479
This function gets each overlapping AABB.
@@ -462,17 +488,20 @@ def overlap_aabbs(self, aabb, method='DFS'):
462
488
method (str): {'DFS'|'BFS'} Method for traversing the tree.
463
489
Setting 'DFS' performs a depth-first search and 'BFS' performs
464
490
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.
465
494
466
495
Returns:
467
496
list: AABB objects in AABBTree that overlap with the input.
468
497
"""
469
- pairs = _overlap_pairs (self , aabb , method )
498
+ pairs = _overlap_pairs (self , aabb , method , closed = closed )
470
499
if len (pairs ) == 0 :
471
500
return []
472
501
boxes , _ = zip (* pairs )
473
502
return list (boxes )
474
503
475
- def overlap_values (self , aabb , method = 'DFS' ):
504
+ def overlap_values (self , aabb , method = 'DFS' , closed = False ):
476
505
"""Get values of overlapping AABBs
477
506
478
507
This function gets the value field of each overlapping AABB.
@@ -487,11 +516,14 @@ def overlap_values(self, aabb, method='DFS'):
487
516
method (str): {'DFS'|'BFS'} Method for traversing the tree.
488
517
Setting 'DFS' performs a depth-first search and 'BFS' performs
489
518
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.
490
522
491
523
Returns:
492
524
list: Value fields of each node that overlaps.
493
525
"""
494
- pairs = _overlap_pairs (self , aabb , method )
526
+ pairs = _overlap_pairs (self , aabb , method , closed = closed )
495
527
if len (pairs ) == 0 :
496
528
return []
497
529
_ , values = zip (* pairs )
@@ -505,7 +537,7 @@ def _merge(lims1, lims2):
505
537
return (lower , upper )
506
538
507
539
508
- def _overlap_pairs (in_tree , aabb , method = 'DFS' , halt = False ):
540
+ def _overlap_pairs (in_tree , aabb , method = 'DFS' , halt = False , closed = False ):
509
541
"""Get overlapping AABBs and values in (AABB, value) pairs
510
542
511
543
*New in version 2.6.0*
@@ -518,8 +550,9 @@ def _overlap_pairs(in_tree, aabb, method='DFS', halt=False):
518
550
method (str): {'DFS'|'BFS'} Method for traversing the tree.
519
551
Setting 'DFS' performs a depth-first search and 'BFS' performs
520
552
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
522
554
added.
555
+ closed (bool): Check for closed box intersection. Defaults to False.
523
556
524
557
Returns:
525
558
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):
530
563
tree = aabb
531
564
532
565
if method == 'DFS' :
533
- pairs = _overlap_dfs (in_tree , tree , halt )
566
+ pairs = _overlap_dfs (in_tree , tree , halt , closed )
534
567
535
568
elif method == 'BFS' :
536
- pairs = _overlap_bfs (in_tree , tree , halt )
569
+ pairs = _overlap_bfs (in_tree , tree , halt , closed )
537
570
else :
538
571
e_str = "method should be 'DFS' or 'BFS', not " + str (method )
539
572
raise ValueError (e_str )
@@ -543,7 +576,7 @@ def _overlap_pairs(in_tree, aabb, method='DFS', halt=False):
543
576
return _unique_pairs (pairs )
544
577
545
578
546
- def _overlap_dfs (in_tree , tree , halt ):
579
+ def _overlap_dfs (in_tree , tree , halt , closed ):
547
580
pairs = []
548
581
549
582
if in_tree .is_leaf :
@@ -556,7 +589,7 @@ def _overlap_dfs(in_tree, tree, halt):
556
589
else :
557
590
tree_branches = [tree .left , tree .right ]
558
591
559
- if not in_tree .aabb .overlaps (tree .aabb ):
592
+ if not in_tree .aabb .overlaps (tree .aabb , closed ):
560
593
return pairs
561
594
562
595
if in_tree .is_leaf and tree .is_leaf :
@@ -565,20 +598,20 @@ def _overlap_dfs(in_tree, tree, halt):
565
598
566
599
for in_branch in in_branches :
567
600
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 )
569
602
pairs .extend (o_pairs )
570
603
if halt and len (pairs ) > 0 :
571
604
return pairs
572
605
return pairs
573
606
574
607
575
- def _overlap_bfs (in_tree , tree , halt ):
608
+ def _overlap_bfs (in_tree , tree , halt , closed ):
576
609
pairs = []
577
610
queue = deque ()
578
611
queue .append ((in_tree , tree ))
579
612
while len (queue ) > 0 :
580
613
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 ):
582
615
if s_node .is_leaf and t_node .is_leaf :
583
616
pairs .append ((s_node .aabb , s_node .value ))
584
617
if halt :
0 commit comments