word_cloud/placement/
spiral_placer.rs

1use crate::geometry::{Rectangle, Vector};
2
3use super::PlacementStrategy;
4
5pub struct SpiralPlacer {
6    viewport: Rectangle,
7    increment: f32,
8}
9
10impl SpiralPlacer {
11    pub fn new(viewport: Rectangle) -> SpiralPlacer {
12        SpiralPlacer {
13            viewport,
14            increment: 0.,
15        }
16    }
17}
18
19impl PlacementStrategy for SpiralPlacer {
20    fn find_next_place(&mut self, start_pos: Option<Vector>, r: &Rectangle) -> Option<Vector> {
21        let start_pos = match start_pos {
22            Some(pos) => pos,
23            None => return Some((self.viewport.center().0, self.viewport.center().1)),
24        };
25
26        let i = self.increment;
27        let angle = 0.1 * i;
28        let x = start_pos.0 as f32 + (1. + angle) * angle.cos();
29        let y = start_pos.1 as f32 + (1. + angle) * angle.sin();
30
31        let next_pos = (x, y);
32
33        if (next_pos.0 < 0.) || (next_pos.1 < 0.) {
34            self.increment = 0.;
35            return None;
36        }
37
38        self.increment += 0.5;
39
40        let next_pos = (next_pos.0 as u32, next_pos.1 as u32);
41        let new_rect = Rectangle::new(next_pos.0, next_pos.1, r.size().0, r.size().1);
42
43        if !self.viewport.contains(&new_rect) {
44            self.increment = 0.;
45            return None;
46        }
47
48        Some(next_pos)
49    }
50}