graphics_shapes/
general_math.rs

1use crate::Coord;
2
3/// Scale `points` (move them towards or away) around the `center` by `factor`
4///
5/// The resulting points distance will be `points[x].distance(center) * factor` but at the same angle
6#[must_use]
7pub fn scale_points(center: Coord, points: &[Coord], factor: f32) -> Vec<Coord> {
8    let mut output = vec![];
9    for point in points {
10        let angle = center.angle_to(*point);
11        let dist = center.distance(*point) as f32 * factor;
12        output.push(Coord::from_angle(
13            center,
14            dist.round().max(0.0) as usize,
15            angle,
16        ));
17    }
18    output
19}
20
21/// Rotate `points` around the `center` by `degrees`
22///
23/// The resulting points at the same distance but at +degrees angle
24#[must_use]
25pub fn rotate_points(center: Coord, points: &[Coord], degrees: isize) -> Vec<Coord> {
26    let mut output = vec![];
27    for point in points {
28        let starting_angle = center.angle_to(*point);
29        let dist = center.distance(*point);
30        output.push(Coord::from_angle(center, dist, starting_angle + degrees));
31    }
32    output
33}
34
35#[cfg(test)]
36mod test {
37    use crate::rotate_points;
38
39    #[test]
40    fn one_point_rotation() {
41        let center = coord!(20, 20);
42        let initial = coord!(30, 20);
43        let no_rotation = rotate_points(center, &[initial], 0);
44        let quarter_rotation = rotate_points(center, &[initial], 90);
45        let half_rotation = rotate_points(center, &[initial], 180);
46        let three_quarter_rotation = rotate_points(center, &[initial], 270);
47        let full_rotation = rotate_points(center, &[initial], 360);
48        assert_eq!(no_rotation, vec![coord!(30, 20)]);
49        assert_eq!(quarter_rotation, vec![coord!(20, 30)]);
50        assert_eq!(half_rotation, vec![coord!(10, 20)]);
51        assert_eq!(three_quarter_rotation, vec![coord!(20, 10)]);
52        assert_eq!(full_rotation, vec![coord!(30, 20)]);
53        let one_degree = rotate_points(center, &[initial], 1);
54        assert_eq!(one_degree, vec![coord!(30, 20)]);
55        let eighth_degree = rotate_points(center, &[initial], 45);
56        assert_eq!(eighth_degree, vec![coord!(27, 27)]);
57    }
58}