turtle_svg/
position.rs

1use std::ops::{
2    Add,
3    Sub,
4    Mul,
5    Div
6};
7
8use crate::angle::Angle;
9
10/// Distances type
11pub type Distance = f64;
12
13/// Location on the plan (x, y)
14#[derive(Clone, Copy)]
15pub struct Pos<T: Sized + Add + Mul + Div + Sub>(pub T, pub T);
16
17/// Macro to implement a type for the Pos struct
18macro_rules! pos_impl {
19    ($t: ty) => {
20        impl From<($t, $t)> for Pos<$t> {
21            fn from(tuple: ($t, $t)) -> Self {
22                Self(
23                    tuple.0 as $t,
24                    tuple.1 as $t
25                )
26            }
27        }
28
29        impl Default for Pos<$t> {
30            fn default() -> Self {
31                Self(0 as $t, 0 as $t)
32            }
33        }
34
35        impl Into<($t, $t)> for Pos<$t> {
36            fn into(self) -> ($t, $t) {
37                (
38                    self.0 as $t,
39                    self.1 as $t
40                )
41            }
42        }
43
44        impl Pos<$t> {
45            /// Return another Pos depending of an angle and a Pos
46            ///
47            /// `t` is the heading angle
48            ///
49            /// `a` is the turn angle
50            ///
51            /// `d` is the distance
52            pub fn next_pos_turn(&self, t: Angle, a: Angle, d: Distance) -> Pos<$t> {
53                let (x0, y0) = (self.0, self.1);
54                let direction = (a.radian() + t.radian());
55
56                let x1 = x0 + (d * direction.cos()) as $t;
57                let y1 = y0 + (d * direction.sin()) as $t;
58        
59                Self(x1, y1)
60            }
61        }
62    };
63}
64
65// Implementing number types for Pos
66pos_impl!(i16);
67pos_impl!(i32);
68pos_impl!(i64);
69pos_impl!(i128);
70pos_impl!(f64);