vox_geometry_rust/
custom_vector_field3.rs1use crate::vector3::Vector3D;
10use crate::field3::Field3;
11use crate::vector_field3::VectorField3;
12use std::sync::{RwLock, Arc};
13
14pub struct CustomVectorField3 {
16 _custom_function: fn(&Vector3D) -> Vector3D,
17 _custom_divergence_function: Option<fn(&Vector3D) -> f64>,
18 _custom_curl_function: Option<fn(&Vector3D) -> Vector3D>,
19 _resolution: f64,
20}
21
22impl CustomVectorField3 {
23 pub fn new(custom_function: fn(&Vector3D) -> Vector3D,
32 custom_divergence_function: Option<fn(&Vector3D) -> f64>,
33 custom_curl_function: Option<fn(&Vector3D) -> Vector3D>,
34 derivative_resolution: Option<f64>) -> CustomVectorField3 {
35 return CustomVectorField3 {
36 _custom_function: custom_function,
37 _custom_divergence_function: custom_divergence_function,
38 _custom_curl_function: custom_curl_function,
39 _resolution: derivative_resolution.unwrap_or(1.0e-3),
40 };
41 }
42
43 pub fn builder() -> Builder {
45 return Builder::new();
46 }
47}
48
49impl Field3 for CustomVectorField3 {}
50
51impl VectorField3 for CustomVectorField3 {
52 fn sample(&self, x: &Vector3D) -> Vector3D {
53 return (self._custom_function)(x);
54 }
55
56 fn divergence(&self, x: &Vector3D) -> f64 {
57 return match self._custom_divergence_function {
58 None => {
59 let left
60 = (self._custom_function)(&(*x - Vector3D::new(0.5 * self._resolution, 0.0, 0.0))).x;
61 let right
62 = (self._custom_function)(&(*x + Vector3D::new(0.5 * self._resolution, 0.0, 0.0))).x;
63 let bottom
64 = (self._custom_function)(&(*x - Vector3D::new(0.0, 0.5 * self._resolution, 0.0))).y;
65 let top
66 = (self._custom_function)(&(*x + Vector3D::new(0.0, 0.5 * self._resolution, 0.0))).y;
67 let back
68 = (self._custom_function)(&(*x - Vector3D::new(0.0, 0.0, 0.5 * self._resolution))).z;
69 let front
70 = (self._custom_function)(&(*x + Vector3D::new(0.0, 0.0, 0.5 * self._resolution))).z;
71
72 (right - left + top - bottom + front - back) / self._resolution
73 }
74 Some(func) => {
75 func(x)
76 }
77 };
78 }
79
80 fn curl(&self, x: &Vector3D) -> Vector3D {
81 return match self._custom_curl_function {
82 None => {
83 let left
84 = (self._custom_function)(&(*x - Vector3D::new(0.5 * self._resolution, 0.0, 0.0)));
85 let right
86 = (self._custom_function)(&(*x + Vector3D::new(0.5 * self._resolution, 0.0, 0.0)));
87 let bottom
88 = (self._custom_function)(&(*x - Vector3D::new(0.0, 0.5 * self._resolution, 0.0)));
89 let top
90 = (self._custom_function)(&(*x + Vector3D::new(0.0, 0.5 * self._resolution, 0.0)));
91 let back
92 = (self._custom_function)(&(*x - Vector3D::new(0.0, 0.0, 0.5 * self._resolution)));
93 let front
94 = (self._custom_function)(&(*x + Vector3D::new(0.0, 0.0, 0.5 * self._resolution)));
95
96 let fx_ym = bottom.x;
97 let fx_yp = top.x;
98 let fx_zm = back.x;
99 let fx_zp = front.x;
100
101 let fy_xm = left.y;
102 let fy_xp = right.y;
103 let fy_zm = back.y;
104 let fy_zp = front.y;
105
106 let fz_xm = left.z;
107 let fz_xp = right.z;
108 let fz_ym = bottom.z;
109 let fz_yp = top.z;
110
111 Vector3D::new(
112 (fz_yp - fz_ym) - (fy_zp - fy_zm),
113 (fx_zp - fx_zm) - (fz_xp - fz_xm),
114 (fy_xp - fy_xm) - (fx_yp - fx_ym)) / self._resolution
115 }
116 Some(func) => {
117 func(x)
118 }
119 };
120 }
121}
122
123pub type CustomVectorField3Ptr = Arc<RwLock<CustomVectorField3>>;
125
126pub struct Builder {
130 _custom_function: Option<fn(&Vector3D) -> Vector3D>,
131 _custom_divergence_function: Option<fn(&Vector3D) -> f64>,
132 _custom_curl_function: Option<fn(&Vector3D) -> Vector3D>,
133 _resolution: f64,
134}
135
136impl Builder {
137 pub fn with_function(&mut self,
139 func: fn(&Vector3D) -> Vector3D) -> &mut Self {
140 self._custom_function = Some(func);
141 return self;
142 }
143
144 pub fn with_divergence_function(&mut self,
146 func: fn(&Vector3D) -> f64) -> &mut Self {
147 self._custom_divergence_function = Some(func);
148 return self;
149 }
150
151 pub fn with_curl_function(&mut self,
153 func: fn(&Vector3D) -> Vector3D) -> &mut Self {
154 self._custom_curl_function = Some(func);
155 return self;
156 }
157
158 pub fn with_derivative_resolution(&mut self, resolution: f64) -> &mut Self {
160 self._resolution = resolution;
161 return self;
162 }
163
164 pub fn build(&mut self) -> CustomVectorField3 {
166 return CustomVectorField3::new(self._custom_function.unwrap(),
167 self._custom_divergence_function,
168 self._custom_curl_function,
169 Some(self._resolution));
170 }
171
172 pub fn make_shared(&mut self) -> CustomVectorField3Ptr {
174 return CustomVectorField3Ptr::new(RwLock::new(self.build()));
175 }
176
177 pub fn new() -> Builder {
179 return Builder {
180 _custom_function: None,
181 _custom_divergence_function: None,
182 _custom_curl_function: None,
183 _resolution: 1.0e-3,
184 };
185 }
186}