oxihuman_export/
pressure_map_export.rs1#![allow(dead_code)]
4
5pub struct PressureMap {
7 pub width: usize,
8 pub height: usize,
9 pub pressures: Vec<f32>,
10}
11
12pub fn new_pressure_map(w: usize, h: usize) -> PressureMap {
13 PressureMap {
14 width: w,
15 height: h,
16 pressures: vec![0.0; w * h],
17 }
18}
19
20pub fn pressure_set(m: &mut PressureMap, x: usize, y: usize, p: f32) {
21 if x < m.width && y < m.height {
22 m.pressures[y * m.width + x] = p;
23 }
24}
25
26pub fn pressure_get(m: &PressureMap, x: usize, y: usize) -> f32 {
27 if x < m.width && y < m.height {
28 m.pressures[y * m.width + x]
29 } else {
30 0.0
31 }
32}
33
34pub fn pressure_total_force(m: &PressureMap, cell_area: f32) -> f32 {
35 m.pressures.iter().sum::<f32>() * cell_area
36}
37
38pub fn pressure_center_of_pressure(m: &PressureMap) -> [f32; 2] {
39 let total: f32 = m.pressures.iter().sum();
40 if total < 1e-9 {
41 return [m.width as f32 * 0.5, m.height as f32 * 0.5];
42 }
43 let mut cx = 0.0f32;
44 let mut cy = 0.0f32;
45 for y in 0..m.height {
46 for x in 0..m.width {
47 let p = m.pressures[y * m.width + x];
48 cx += p * x as f32;
49 cy += p * y as f32;
50 }
51 }
52 [cx / total, cy / total]
53}
54
55pub fn pressure_max(m: &PressureMap) -> f32 {
56 m.pressures
57 .iter()
58 .cloned()
59 .fold(f32::NEG_INFINITY, f32::max)
60}
61
62pub fn pressure_to_bytes(m: &PressureMap) -> Vec<u8> {
63 let mut out = Vec::with_capacity(m.pressures.len() * 4);
64 for &p in &m.pressures {
65 out.extend_from_slice(&p.to_le_bytes());
66 }
67 out
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_new_pressure_map_size() {
76 let m = new_pressure_map(5, 5);
77 assert_eq!(m.pressures.len(), 25);
78 }
79
80 #[test]
81 fn test_pressure_set_get() {
82 let mut m = new_pressure_map(4, 4);
83 pressure_set(&mut m, 2, 1, 100.0);
84 assert!((pressure_get(&m, 2, 1) - 100.0).abs() < 1e-4);
85 }
86
87 #[test]
88 fn test_pressure_get_oob() {
89 let m = new_pressure_map(4, 4);
90 assert!((pressure_get(&m, 10, 10) - 0.0).abs() < 1e-6);
91 }
92
93 #[test]
94 fn test_pressure_total_force() {
95 let mut m = new_pressure_map(2, 1);
96 pressure_set(&mut m, 0, 0, 10.0);
97 pressure_set(&mut m, 1, 0, 20.0);
98 assert!((pressure_total_force(&m, 0.01) - 0.3).abs() < 1e-5);
99 }
100
101 #[test]
102 fn test_pressure_center_of_pressure() {
103 let mut m = new_pressure_map(3, 1);
104 pressure_set(&mut m, 0, 0, 0.0);
105 pressure_set(&mut m, 1, 0, 1.0);
106 pressure_set(&mut m, 2, 0, 0.0);
107 let cop = pressure_center_of_pressure(&m);
108 assert!((cop[0] - 1.0).abs() < 1e-4);
109 }
110
111 #[test]
112 fn test_pressure_max() {
113 let mut m = new_pressure_map(3, 1);
114 pressure_set(&mut m, 0, 0, 50.0);
115 pressure_set(&mut m, 1, 0, 200.0);
116 pressure_set(&mut m, 2, 0, 75.0);
117 assert!((pressure_max(&m) - 200.0).abs() < 1e-4);
118 }
119
120 #[test]
121 fn test_pressure_to_bytes_len() {
122 let m = new_pressure_map(4, 4);
123 assert_eq!(pressure_to_bytes(&m).len(), 64);
124 }
125
126 #[test]
127 fn test_pressure_center_empty() {
128 let m = new_pressure_map(4, 4);
129 let _ = pressure_center_of_pressure(&m);
131 }
132}