1use crate::circle::Circle;
2use crate::particle::Particle;
3
4#[derive(Debug, Copy, Clone)]
5pub struct Link {
6 pub particle_a: usize,
8 pub particle_b: usize,
9 pub target_distance: f32,
10}
11
12#[derive(Debug, Copy, Clone)]
13pub struct ParticleLink {
14 pub link: Link,
15}
16
17impl ParticleLink {
18 pub fn solve(&mut self, particles: &mut Vec<Particle>) {
19 let split = particles.split_at_mut(self.link.particle_b);
20 let particle_a = &mut split.0[self.link.particle_a];
21 let particle_b = &mut split.1[0];
22 let dist_vec = particle_a.pos - particle_b.pos;
23 let dist = dist_vec.magnitude();
24 let normal = dist_vec.normalize();
25 particle_a.pos -= normal * (dist - self.link.target_distance) * 0.5;
26 particle_b.pos += normal * (dist - self.link.target_distance) * 0.5;
27 }
28}
29
30#[derive(Debug, Copy, Clone)]
31pub struct CircleLink {
32 pub link: Link,
33}
34
35impl CircleLink {
36 pub fn solve(&mut self, circles: &mut Vec<Circle>) {
37 let split = circles.split_at_mut(self.link.particle_b);
38 let circle_a = &mut split.0[self.link.particle_a];
39 let circle_b = &mut split.1[0];
40 let dist_vec = circle_a.point.pos - circle_b.point.pos;
41 let dist = dist_vec.magnitude();
42 let normal = dist_vec.normalize();
43 let c_a_rad_sqr = circle_a.radius * circle_a.radius;
44 let c_b_rad_sqr = circle_b.radius * circle_b.radius;
45 let scale = 1.0 / (c_a_rad_sqr + c_b_rad_sqr);
46 circle_a.point.pos -= normal * (dist - self.link.target_distance) * scale * c_b_rad_sqr;
47 circle_b.point.pos += normal * (dist - self.link.target_distance) * scale * c_a_rad_sqr;
48 }
49}