@@ -3,6 +3,7 @@ use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterato
33
44use crate :: indices:: MutableIndices ;
55use crate :: r#type:: IndexableNum ;
6+ use crate :: rtree:: sort:: util:: swap;
67use crate :: rtree:: sort:: { Sort , SortParams } ;
78
89/// An implementation of sort-tile-recursive (STR) sorting.
@@ -98,6 +99,17 @@ impl<N: IndexableNum> Sort<N> for STRSort {
9899 }
99100}
100101
102+ /// Max is only implemented for `Ord` types, but float types do not implement `Ord`.
103+ ///
104+ /// So we use this as a hack to get the maximum of two PartialOrd values.
105+ fn partial_ord_max < N : IndexableNum > ( a : N , b : N ) -> N {
106+ if a > b {
107+ a
108+ } else {
109+ b
110+ }
111+ }
112+
101113/// Custom quicksort that partially sorts bbox data alongside their sort values.
102114// Partially taken from static_aabb2d_index under the MIT/Apache license
103115fn sort < N : IndexableNum > (
@@ -114,8 +126,22 @@ fn sort<N: IndexableNum>(
114126 return ;
115127 }
116128
117- let midpoint = ( left + right) / 2 ;
118- let pivot = values[ midpoint] ;
129+ // apply median of three method
130+ let start = values[ left] ;
131+ let mid = values[ ( left + right) >> 1 ] ;
132+ let end = values[ right] ;
133+
134+ let x = partial_ord_max ( start, mid) ;
135+ let pivot = if end > x {
136+ x
137+ } else if x == start {
138+ partial_ord_max ( mid, end)
139+ } else if x == mid {
140+ partial_ord_max ( start, end)
141+ } else {
142+ end
143+ } ;
144+
119145 let mut i = left. wrapping_sub ( 1 ) ;
120146 let mut j = right. wrapping_add ( 1 ) ;
121147
@@ -144,24 +170,3 @@ fn sort<N: IndexableNum>(
144170 sort ( values, boxes, indices, left, j, node_size) ;
145171 sort ( values, boxes, indices, j. wrapping_add ( 1 ) , right, node_size) ;
146172}
147-
148- /// Swap two values and two corresponding boxes.
149- #[ inline]
150- fn swap < N : IndexableNum > (
151- values : & mut [ N ] ,
152- boxes : & mut [ N ] ,
153- indices : & mut MutableIndices ,
154- i : usize ,
155- j : usize ,
156- ) {
157- values. swap ( i, j) ;
158-
159- let k = 4 * i;
160- let m = 4 * j;
161- boxes. swap ( k, m) ;
162- boxes. swap ( k + 1 , m + 1 ) ;
163- boxes. swap ( k + 2 , m + 2 ) ;
164- boxes. swap ( k + 3 , m + 3 ) ;
165-
166- indices. swap ( i, j) ;
167- }
0 commit comments