static_bushes/kdbush/
sort.rs1use crate::{kdbush::AllowedNumber, util::IndexVec};
2
3pub fn sort_kd<T: AllowedNumber>(
4 ids: &mut IndexVec,
5 coords: &mut [T],
6 node_size: usize,
7 left: usize,
8 right: usize,
9 axis: usize,
10) {
11 if right - left <= node_size {
12 return;
13 }
14
15 let m = (left + right) >> 1; select(ids, coords, m, left, right, axis);
20
21 sort_kd(ids, coords, node_size, left, m - 1, 1 - axis);
23 sort_kd(ids, coords, node_size, m + 1, right, 1 - axis);
24}
25
26fn select<T: AllowedNumber>(
29 ids: &mut IndexVec,
30 coords: &mut [T],
31 k: usize,
32 mut left: usize,
33 mut right: usize,
34 axis: usize,
35) {
36 while right > left {
37 if right - left > 600 {
38 let n = (right - left + 1) as f64;
39 let m = (k - left + 1) as f64;
40 let fk = k as f64;
41
42 let z = n.ln();
43 let s = 0.5 * (2.0 * z / 3.0).exp();
44 let sd =
45 0.5 * (z * s * (n - s) / n).sqrt() * (if m - n / 2.0 < 0.0 { -1.0 } else { 1.0 });
46 let new_left = max(left, (fk - m * s / n + sd).floor() as usize);
47 let new_right = min(right, (fk + (n - m) * s / n + sd).floor() as usize);
48 select(ids, coords, k, new_left, new_right, axis);
49 }
50
51 let t = coords[2 * k + axis];
52 let mut i = left;
53 let mut j = right;
54
55 swap_item(ids, coords, left, k);
56 if coords[2 * right + axis] > t {
57 swap_item(ids, coords, left, right);
58 }
59
60 while i < j {
61 swap_item(ids, coords, i, j);
62 i += 1;
63 j -= 1;
64 while coords[2 * i + axis] < t {
65 i += 1
66 }
67 while coords[2 * j + axis] > t {
68 j -= 1
69 }
70 }
71
72 if coords[2 * left + axis] == t {
73 swap_item(ids, coords, left, j)
74 } else {
75 j += 1;
76 swap_item(ids, coords, j, right);
77 }
78
79 if j <= k {
80 left = j + 1;
81 }
82 if k <= j {
83 right = j - 1;
84 }
85 }
86}
87
88fn swap_item<T: AllowedNumber>(ids: &mut IndexVec, coords: &mut [T], i: usize, j: usize) {
89 ids.swap(i, j);
90 coords.swap(2 * i, 2 * j);
91 coords.swap(2 * i + 1, 2 * j + 1);
92}
93
94#[inline(always)]
97fn min<U: PartialOrd>(a: U, b: U) -> U {
98 if a <= b {
99 a
100 } else {
101 b
102 }
103}
104
105#[inline(always)]
106fn max<U: PartialOrd>(a: U, b: U) -> U {
107 if b >= a {
108 b
109 } else {
110 a
111 }
112}