@@ -26,24 +26,16 @@ fn child_index_for_rect(boundary: &Rect, r: &Rect) -> Option<usize> {
2626 let cx = 0.5 * ( boundary. min_x + boundary. max_x ) ;
2727 let cy = 0.5 * ( boundary. min_y + boundary. max_y ) ;
2828
29- // Does r fit entirely on one side of the vertical split?
30- let in_left = r. max_x <= cx;
31- let in_right = r. min_x >= cx;
32-
33- // Does r fit entirely on one side of the horizontal split?
34- let in_bottom = r. max_y <= cy;
35- let in_top = r. min_y >= cy;
36-
37- let x_side = if in_left { Some ( 0 ) } else if in_right { Some ( 1 ) } else { None } ;
38- let y_side = if in_bottom { Some ( 0 ) } else if in_top { Some ( 1 ) } else { None } ;
39-
40- match ( x_side, y_side) {
41- ( Some ( 0 ) , Some ( 0 ) ) => Some ( 0 ) ,
42- ( Some ( 1 ) , Some ( 0 ) ) => Some ( 1 ) ,
43- ( Some ( 0 ) , Some ( 1 ) ) => Some ( 2 ) ,
44- ( Some ( 1 ) , Some ( 1 ) ) => Some ( 3 ) ,
45- _ => None , // Spans split line(s) so it must live at this node
29+ // fits entirely on one side per axis?
30+ let fits_x = r. max_x <= cx || r. min_x >= cx;
31+ let fits_y = r. max_y <= cy || r. min_y >= cy;
32+ if !( fits_x && fits_y) {
33+ return None ;
4634 }
35+ // right=1 if min_x >= cx, top=1 if min_y >= cy
36+ let ix = ( r. min_x >= cx) as usize ;
37+ let iy = ( r. min_y >= cy) as usize ;
38+ Some ( ix | ( iy << 1 ) ) // 0..3
4739}
4840
4941#[ inline( always) ]
@@ -120,10 +112,10 @@ impl RectQuadTree {
120112 let cy = 0.5 * ( self . boundary . min_y + self . boundary . max_y ) ;
121113
122114 let quads = [
123- Rect { min_x : self . boundary . min_x , min_y : self . boundary . min_y , max_x : cx, max_y : cy } , // 0
124- Rect { min_x : cx, min_y : self . boundary . min_y , max_x : self . boundary . max_x , max_y : cy } , // 1
125- Rect { min_x : self . boundary . min_x , min_y : cy, max_x : cx, max_y : self . boundary . max_y } , // 2
126- Rect { min_x : cx, min_y : cy, max_x : self . boundary . max_x , max_y : self . boundary . max_y } , // 3
115+ Rect { min_x : self . boundary . min_x , min_y : self . boundary . min_y , max_x : cx, max_y : cy } ,
116+ Rect { min_x : cx, min_y : self . boundary . min_y , max_x : self . boundary . max_x , max_y : cy } ,
117+ Rect { min_x : self . boundary . min_x , min_y : cy, max_x : cx, max_y : self . boundary . max_y } ,
118+ Rect { min_x : cx, min_y : cy, max_x : self . boundary . max_x , max_y : self . boundary . max_y } ,
127119 ] ;
128120
129121 let d = self . depth + 1 ;
@@ -134,16 +126,19 @@ impl RectQuadTree {
134126 RectQuadTree :: new_child ( quads[ 3 ] , self . capacity , d, self . max_depth ) ,
135127 ] ;
136128
137- // Move any items that fully fit a child
138- let mut stay: Vec < RectItem > = Vec :: new ( ) ;
139- for it in self . items . drain ( ..) {
140- if let Some ( idx) = child_index_for_rect ( & self . boundary , & it. rect ) {
129+ // Move any items that fully fit a child, in place
130+ let mut i = 0 ;
131+ while i < self . items . len ( ) {
132+ let rect = self . items [ i] . rect ;
133+ if let Some ( idx) = child_index_for_rect ( & self . boundary , & rect) {
134+ let it = self . items . swap_remove ( i) ;
141135 kids[ idx] . insert ( it) ;
136+ // do not advance i, we swapped in a new element at i
142137 } else {
143- stay . push ( it ) ;
138+ i += 1 ;
144139 }
145140 }
146- self . items = stay ;
141+
147142 self . children = Some ( Box :: new ( kids) ) ;
148143 }
149144
@@ -159,7 +154,7 @@ impl RectQuadTree {
159154 #[ derive( Copy , Clone ) ]
160155 enum Mode { Filter , ReportAll }
161156
162- let mut out: Vec < ( u64 , Rect ) > = Vec :: with_capacity ( 128 ) ;
157+ let mut out: SmallVec < [ ( u64 , Rect ) ; 128 ] > = SmallVec :: new ( ) ;
163158 let mut stack: SmallVec < [ ( & RectQuadTree , Mode ) ; 64 ] > = SmallVec :: new ( ) ;
164159 stack. push ( ( self , Mode :: Filter ) ) ;
165160
@@ -213,7 +208,7 @@ impl RectQuadTree {
213208 }
214209 }
215210
216- out
211+ out. into_vec ( )
217212 }
218213
219214 /// Convenience if you only want ids.
0 commit comments