vox_geometry_rust/
custom_vector_field2.rs1use crate::vector2::Vector2D;
10use crate::field2::Field2;
11use crate::vector_field2::VectorField2;
12use std::sync::{RwLock, Arc};
13
14pub struct CustomVectorField2 {
16 _custom_function: fn(&Vector2D) -> Vector2D,
17 _custom_divergence_function: Option<fn(&Vector2D) -> f64>,
18 _custom_curl_function: Option<fn(&Vector2D) -> f64>,
19 _resolution: f64,
20}
21
22impl CustomVectorField2 {
23 pub fn new(custom_function: fn(&Vector2D) -> Vector2D,
32 custom_divergence_function: Option<fn(&Vector2D) -> f64>,
33 custom_curl_function: Option<fn(&Vector2D) -> f64>,
34 derivative_resolution: Option<f64>) -> CustomVectorField2 {
35 return CustomVectorField2 {
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 Field2 for CustomVectorField2 {}
50
51impl VectorField2 for CustomVectorField2 {
52 fn sample(&self, x: &Vector2D) -> Vector2D {
53 return (self._custom_function)(x);
54 }
55
56 fn divergence(&self, x: &Vector2D) -> f64 {
57 return match self._custom_divergence_function {
58 None => {
59 let left = (self._custom_function)(&(*x - Vector2D::new(0.5 * self._resolution, 0.0))).x;
60 let right = (self._custom_function)(&(*x + Vector2D::new(0.5 * self._resolution, 0.0))).x;
61 let bottom = (self._custom_function)(&(*x - Vector2D::new(0.0, 0.5 * self._resolution))).y;
62 let top = (self._custom_function)(&(*x + Vector2D::new(0.0, 0.5 * self._resolution))).y;
63
64 (right - left + top - bottom) / self._resolution
65 }
66 Some(func) => {
67 func(x)
68 }
69 };
70 }
71
72 fn curl(&self, x: &Vector2D) -> f64 {
73 match self._custom_curl_function {
74 None => {
75 let left = (self._custom_function)(&(*x - Vector2D::new(0.5 * self._resolution, 0.0))).y;
76 let right = (self._custom_function)(&(*x + Vector2D::new(0.5 * self._resolution, 0.0))).y;
77 let bottom = (self._custom_function)(&(*x - Vector2D::new(0.0, 0.5 * self._resolution))).x;
78 let top = (self._custom_function)(&(*x + Vector2D::new(0.0, 0.5 * self._resolution))).x;
79
80 return (top - bottom - right + left) / self._resolution;
81 }
82 Some(func) => {
83 return func(x);
84 }
85 }
86 }
87}
88
89pub type CustomVectorField2Ptr = Arc<RwLock<CustomVectorField2>>;
91
92pub struct Builder {
96 _custom_function: Option<fn(&Vector2D) -> Vector2D>,
97 _custom_divergence_function: Option<fn(&Vector2D) -> f64>,
98 _custom_curl_function: Option<fn(&Vector2D) -> f64>,
99 _resolution: f64,
100}
101
102impl Builder {
103 pub fn with_function(&mut self,
105 func: fn(&Vector2D) -> Vector2D) -> &mut Self {
106 self._custom_function = Some(func);
107 return self;
108 }
109
110 pub fn with_divergence_function(&mut self,
112 func: fn(&Vector2D) -> f64) -> &mut Self {
113 self._custom_divergence_function = Some(func);
114 return self;
115 }
116
117 pub fn with_curl_function(&mut self,
119 func: fn(&Vector2D) -> f64) -> &mut Self {
120 self._custom_curl_function = Some(func);
121 return self;
122 }
123
124 pub fn with_derivative_resolution(&mut self, resolution: f64) -> &mut Self {
126 self._resolution = resolution;
127 return self;
128 }
129
130 pub fn build(&mut self) -> CustomVectorField2 {
132 return CustomVectorField2::new(self._custom_function.unwrap(),
133 self._custom_divergence_function,
134 self._custom_curl_function,
135 Some(self._resolution));
136 }
137
138 pub fn make_shared(&mut self) -> CustomVectorField2Ptr {
140 return CustomVectorField2Ptr::new(RwLock::new(self.build()));
141 }
142
143 pub fn new() -> Builder {
145 return Builder {
146 _custom_function: None,
147 _custom_divergence_function: None,
148 _custom_curl_function: None,
149 _resolution: 1.0e-3,
150 };
151 }
152}