1
2#![feature(int_log)]
8
9use num::Float;
10use std::marker::PhantomData;
11const SCALE_HEIGHT: f64 = 0.7071067811865475244;
12
13
14#[derive(Clone, Copy, Debug)]
15pub struct HTree<T> {
16 order: usize,
17 _marker: PhantomData<T>,
18}
19
20pub struct HTreeIterator<T>
21where
22 T: Float,
23{
24 h_tree: HTree<T>,
25 index: usize,
26}
27
28impl<T> HTree<T>
29where
30 T: Float,
31{
32
33 pub fn new(order: usize) -> HTree<T> {
42 HTree {
43 order,
44 _marker: PhantomData {},
45 }
46 }
47}
48impl<T> Iterator for HTreeIterator<T>
49where
50 T: Float,
51{
52 type Item = ((T, T), (T, T));
53 fn next(&mut self) -> Option<Self::Item> {
54 self.index += 1;
55 let order_index = self.index.ilog2() as u32;
56 if order_index > self.h_tree.order as u32 {
57 return None;
58 }
59 let iteration_index = self.index as u32 - (1u32 << order_index);
60
61 let num_vertical_rectangles = 1u32 << (order_index + 1) / 2;
62 let num_horizontal_rectangles = 1u32 << order_index / 2 + 1;
63 let num_rectangles = num_vertical_rectangles * num_horizontal_rectangles;
64 assert_eq!(num_rectangles >= iteration_index * 2, true);
65
66 let rectangle_index = 2 * iteration_index;
67 let num_x_start;
68 let num_y_start;
69 let num_x_end;
70 let num_y_end;
71 if order_index % 2 == 1 {
72 num_y_start = rectangle_index % num_vertical_rectangles;
75 num_x_start = (rectangle_index - num_y_start) / num_vertical_rectangles;
76 num_y_end = (rectangle_index + 1) % num_vertical_rectangles;
77 num_x_end = ((rectangle_index + 1) - num_y_end) / num_vertical_rectangles;
78 } else {
79 num_x_start = rectangle_index % num_horizontal_rectangles;
82 num_y_start = (rectangle_index - num_x_start) / num_horizontal_rectangles;
83 num_x_end = (rectangle_index + 1) % num_horizontal_rectangles;
84 num_y_end = ((rectangle_index + 1) - num_x_end) / num_horizontal_rectangles;
85 }
86
87 let x_start: T = (T::from(num_x_start).unwrap() + T::from(0.5).unwrap())
88 / T::from(num_horizontal_rectangles).unwrap();
89 let x_end: T = (T::from(num_x_end).unwrap() + T::from(0.5).unwrap())
90 / T::from(num_horizontal_rectangles).unwrap();
91 let y_start: T = (T::from(num_y_start).unwrap() + T::from(0.5).unwrap())
92 / T::from(num_vertical_rectangles).unwrap();
93 let y_end: T = (T::from(num_y_end).unwrap() + T::from(0.5).unwrap())
94 / T::from(num_vertical_rectangles).unwrap();
95 Some((
96 (x_start, y_start * T::from(SCALE_HEIGHT).unwrap()),
97 (x_end, y_end * T::from(SCALE_HEIGHT).unwrap()),
98 ))
99 }
100}
101
102impl<T> IntoIterator for HTree<T>
103where
104 T: Float,
105{
106 type Item = ((T, T), (T, T));
107 type IntoIter = HTreeIterator<T>;
108
109
110 fn into_iter(self) -> Self::IntoIter {
128 HTreeIterator {
129 h_tree: self,
130 index: 0,
131 }
132 }
133}
134
135