1use serde::{Deserialize, Serialize};
5
6pub trait PhysicalObject {
8 fn compute_force(&self, position: [f32; 3]) -> [f32; 3];
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Sphere {
15 pub center: [f32; 3],
16 pub radius: f32,
17 pub stiffness: f32, pub magnetism: f32, pub damping: f32, }
21
22impl PhysicalObject for Sphere {
23 fn compute_force(&self, position: [f32; 3]) -> [f32; 3] {
24 let dx = position[0] - self.center[0];
25 let dy = position[1] - self.center[1];
26 let dz = position[2] - self.center[2];
27 let distance = (dx * dx + dy * dy + dz * dz).sqrt();
28 if distance < self.radius {
29 let norm_dx = dx / distance;
31 let norm_dy = dy / distance;
32 let norm_dz = dz / distance;
33 let penetration = self.radius - distance;
34 [
35 self.stiffness * penetration * norm_dx,
36 self.stiffness * penetration * norm_dy,
37 self.stiffness * penetration * norm_dz,
38 ]
39 } else if distance > 0.0 {
40 let norm_dx = (self.center[0] - position[0]) / distance;
42 let norm_dy = (self.center[1] - position[1]) / distance;
43 let norm_dz = (self.center[2] - position[2]) / distance;
44 [
45 self.magnetism * norm_dx,
46 self.magnetism * norm_dy,
47 self.magnetism * norm_dz,
48 ]
49 } else {
50 [0.0, 0.0, 0.0]
51 }
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct Cube {
58 pub center: [f32; 3],
59 pub size: f32, pub stiffness: f32, pub magnetism: f32, pub damping: f32, }
64
65impl PhysicalObject for Cube {
66 fn compute_force(&self, position: [f32; 3]) -> [f32; 3] {
67 let half = self.size / 2.0;
70 let mut force = [0.0_f32, 0.0, 0.0];
71 for i in 0..3 {
72 let diff = position[i] - self.center[i];
73 if diff.abs() < half {
74 force[i] = -self.stiffness * diff;
75 } else {
76 force[i] = if diff > 0.0 {
78 self.magnetism
79 } else {
80 -self.magnetism
81 };
82 }
83 }
84 force
85 }
86}
87
88
89pub fn compute_total_force(position: [f32; 3], objects: &[Box<dyn PhysicalObject>]) -> [f32; 3] {
101 let mut total = [0.0_f32, 0.0, 0.0];
102 for obj in objects {
103 let f = obj.compute_force(position);
104 total[0] += f[0];
105 total[1] += f[1];
106 total[2] += f[2];
107 }
108 total
109}