bendy2d/
link.rs

1use crate::circle::Circle;
2use crate::particle::Particle;
3
4#[derive(Debug, Copy, Clone)]
5pub struct Link {
6    // particle_a needs to be lower than particle_b
7    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}