1use crate::Vect;
2use std::mem;
3
4#[derive(Copy, Clone, Debug)]
7pub struct Base {
8 pub a: Vect,
9 pub b: Vect,
10 l: f32,
11}
12
13impl Base {
14 pub const ZERO: Self = Self { a: Vect::ZERO, b: Vect::ZERO, l: 0f32 };
15
16 #[inline]
17 pub fn new(a: Vect, b: Vect) -> Self {
18 Self{ a, b, l: (a - b).len() }
19 }
20
21 #[inline]
23 pub fn rotation(&self) -> f32 {
24 (self.a - self.b).ang()
25 }
26
27 #[inline]
29 pub fn center(&self) -> Vect {
30 self.a + (self.b - self.a)/2f32
31 }
32
33
34 fn mv(&mut self, delta: Vect) {
35 self.a += delta;
36 self.b += delta;
37 }
38
39 #[inline]
41 pub fn rotate_around(&mut self, delta: f32, point: Vect) {
42 self.mv(point.inverted());
43 self.a = self.a.rot(delta);
44 self.b = self.b.rot(delta);
45 self.mv(point);
46 }
47
48 #[inline]
50 pub fn rotate(&mut self, delta: f32) {
51 self.rotate_around(delta, self.center());
52 }
53
54 #[inline]
56 pub fn dir(&self) -> Vect {
57 self.a - self.b
58 }
59
60 #[inline]
62 pub fn set_pos(&mut self, pos: Vect) {
63 let d = self.dir()/2f32;
64 self.a = pos + d;
65 self.b = pos - d;
66 }
67
68 #[inline]
70 pub fn set_rot(&mut self, rot: f32) {
71 let d = Vect::rad(rot ,self.l/2f32);
72 let c = self.center();
73 self.a = d + c;
74 self.b = d.inverted() + c;
75 }
76
77 #[inline]
81 pub fn pull(&mut self, mut force: Vect) -> Vect {
82 let mut l = force.len();
83
84 if l == 0.0 {
85 return Vect::ZERO
86 }
87
88 let mut extra = Vect::ZERO;
89
90 if l > self.l {
91 extra = force.norm() * self.l;
92 self.b = self.a + extra;
93 mem::swap(&mut self.a, &mut self.b);
94
95 force -= extra;
96 l -= self.l
97 }
98
99 let dir = self.dir();
100
101 let projected = Vect::rad(dir.ang_to(force), l);
102 let back_move = self.l - (self.l*self.l-projected.y*projected.y).sqrt() + projected.x;
103 let back_force = dir.norm() * back_move;
104
105 self.a += force;
106 self.b += back_force;
107
108 back_force + extra
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use crate::math::base::Base;
115 use crate::Vect;
116 #[test]
117 fn pull_test() {
118 let mut base = Base::new(vect!(0, 0), vect!(0, 100));
119 base.pull(vect!(1000, 0));
120 println!("{:?}", base);
121 }
122}