1#![deny(missing_docs)]
2
3extern crate vecmath;
63
64pub use vecmath::vec3_add as add3;
65pub use vecmath::vec2_add as add2;
66pub use vecmath::vec3_sub as sub3;
67pub use vecmath::vec2_sub as sub2;
68pub use vecmath::vec3_len as len3;
69pub use vecmath::vec2_len as len2;
70pub use vecmath::vec3_scale as scale3;
71pub use vecmath::vec2_scale as scale2;
72pub use vecmath::vec2_cast as cast2;
73pub use vecmath::vec3_cast as cast3;
74pub use vecmath::traits::*;
75
76use std::sync::Arc;
77
78pub type Fn1<T> = Arc<Fn(T) -> [T; 3] + Sync + Send>;
80pub type Fn2<T> = Arc<Fn([T; 2]) -> [T; 3] + Sync + Send>;
82pub type Fn3<T> = Arc<Fn([T; 3]) -> [T; 3] + Sync + Send>;
84
85pub fn lin<T: Float>(a: [T; 3], b: [T; 3]) -> Fn1<T> {
87 return Arc::new(move |t| add3(a, scale3(sub3(b, a), t)))
88}
89
90pub fn lin2<T: Float>(a: Fn1<T>, b: Fn1<T>) -> Fn1<T> {
92 return Arc::new(move |t| {
93 add3(scale3(a(t), <T as One>::one() - t), scale3(b(t), t))
94 })
95}
96
97pub fn qbez<T: Float>(a: [T; 3], b: [T; 3], c: [T; 3]) -> Fn1<T> {
99 lin2(lin(a, b), lin(b, c))
100}
101
102pub fn cbez<T: Float>(
104 a: [T; 3],
105 b: [T; 3],
106 c: [T; 3],
107 d: [T; 3],
108) -> Fn1<T> {
109 lin2(lin(a, b), lin(c, d))
110}
111
112pub fn cquad<T: Float>(
114 smooth: T,
115 ab: Fn1<T>,
116 cd: Fn1<T>,
117 ac: Fn1<T>,
118 bd: Fn1<T>
119) -> Fn2<T>
120 where f64: Cast<T>
121{
122 let _1: T = One::one();
123 let _0: T = Zero::zero();
124 let _05: T = 0.5.cast();
125 let _4: T = 4.0.cast();
126 return Arc::new(move |t| {
127 let abx = ab(t[1]);
128 let cdx = cd(t[1]);
129 let acx = ac(t[0]);
130 let bdx = bd(t[0]);
131
132 let w0 = _4 * (t[0] - _05) * (t[0] - _05) + smooth;
133 let w1 = _4 * (t[1] - _05) * (t[1] - _05) + smooth;
134 let (w0, w1) = (w0 / (w0 + w1), w1 / (w0 + w1));
136
137 let a = add3(abx, scale3(sub3(cdx, abx), t[0]));
138 let b = add3(acx, scale3(sub3(bdx, acx), t[1]));
139 if w0 == _1 {a}
140 else if w1 == _1 {b}
141 else if (w0 + w1) == _0 {
142 scale3(add3(a, b), _05)
143 }
144 else {
145 add3(scale3(a, w0), scale3(b, w1))
146 }
147 })
148}
149
150pub fn con<T: Float>(w: T, a: Fn1<T>, b: Fn1<T>) -> Fn1<T> {
154 return Arc::new(move |t| {
155 if t < w {a(t / w)}
156 else {b((t - w) / (<T as One>::one() - w))}
157 })
158}
159
160pub fn conx2<T: Float>(wx: T, a: Fn2<T>, b: Fn2<T>) -> Fn2<T> {
162 return Arc::new(move |t| {
163 if t[0] < wx {a([t[0] / wx, t[1]])}
164 else {b(([(t[0] - wx) / (<T as One>::one() - wx), t[1]]))}
165 })
166}
167
168pub fn cony2<T: Float>(wy: T, a: Fn2<T>, b: Fn2<T>) -> Fn2<T> {
170 return Arc::new(move |t| {
171 if t[1] < wy {a([t[0], t[1] / wy])}
172 else {b([t[0], (t[1] - wy) / (<T as One>::one() - wy)])}
173 })
174}
175
176pub fn conx3<T: Float>(wx: T, a: Fn3<T>, b: Fn3<T>) -> Fn3<T> {
178 return Arc::new(move |t| {
179 if t[0] < wx {a([t[0] / wx, t[1], t[2]])}
180 else {b(([(t[0] - wx) / (<T as One>::one() - wx), t[1], t[2]]))}
181 })
182}
183
184pub fn cony3<T: Float>(wy: T, a: Fn3<T>, b: Fn3<T>) -> Fn3<T> {
186 return Arc::new(move |t| {
187 if t[1] < wy {a([t[0], t[1] / wy, t[2]])}
188 else {b([t[0], (t[1] - wy) / (<T as One>::one() - wy), t[2]])}
189 })
190}
191
192pub fn conz3<T: Float>(wz: T, a: Fn3<T>, b: Fn3<T>) -> Fn3<T> {
194 return Arc::new(move |t| {
195 if t[2] < wz {a([t[0], t[1], t[2] / wz])}
196 else {b([t[0], t[1], (t[2] - wz) / (<T as One>::one() - wz)])}
197 })
198}
199
200pub fn mx<T: 'static, U: Float>(
202 x: U,
203 a: Arc<Fn(T) -> [U; 3] + Sync + Send>
204) -> Arc<Fn(T) -> [U; 3] + Sync + Send>
205 where f64: Cast<U>
206{
207 return Arc::new(move |t| {
208 let pos = a(t);
209 [2.0.cast() * x - pos[0], pos[1], pos[2]]
210 })
211}
212
213pub fn my<T: 'static, U: Float>(
215 y: U,
216 a: Arc<Fn(T) -> [U; 3] + Sync + Send>
217) -> Arc<Fn(T) -> [U; 3] + Sync + Send>
218 where f64: Cast<U>
219{
220 return Arc::new(move |t| {
221 let pos = a(t);
222 [pos[0], 2.0.cast() * y - pos[1], pos[2]]
223 })
224}
225
226pub fn mz<T: 'static, U: Float>(
228 z: U,
229 a: Arc<Fn(T) -> [U; 3] + Sync + Send>
230) -> Arc<Fn(T) -> [U; 3] + Sync + Send>
231 where f64: Cast<U>
232{
233 return Arc::new(move |t| {
234 let pos = a(t);
235 [pos[0], pos[1], 2.0.cast() * z - pos[2]]
236 })
237}
238
239pub fn mirx2<T: Float>(x: T, a: Fn2<T>) -> Fn2<T>
241 where f64: Cast<T>
242{
243 conx2(0.5.cast(), a.clone(), mx(x, a))
244}
245
246pub fn miry2<T: Float>(y: T, a: Fn2<T>) -> Fn2<T>
248 where f64: Cast<T>
249{
250 cony2(0.5.cast(), a.clone(), my(y, a))
251}
252
253pub fn mirx3<T: Float>(x: T, a: Fn3<T>) -> Fn3<T>
255 where f64: Cast<T>
256{
257 conx3(0.5.cast(), a.clone(), mx(x, a))
258}
259
260pub fn miry3<T: Float>(y: T, a: Fn3<T>) -> Fn3<T>
262 where f64: Cast<T>
263{
264 cony3(0.5.cast(), a.clone(), my(y, a))
265}
266
267pub fn mirz3<T: Float>(z: T, a: Fn3<T>) -> Fn3<T>
269 where f64: Cast<T>
270{
271 conz3(0.5.cast(), a.clone(), mz(z, a))
272}
273
274pub fn rev<T: Float>(a: Fn1<T>) -> Fn1<T> {
276 seg1([One::one(), Zero::zero()], a)
277}
278
279pub fn off<T: 'static, U: Float>(
281 pos: [U; 3],
282 a: Arc<Fn(T) -> [U; 3] + Sync + Send>
283) -> Arc<Fn(T) -> [U; 3] + Sync + Send> {
284 return Arc::new(move |t| add3(a(t), pos))
285}
286
287pub fn contour<T: Float>(a: Fn2<T>) -> Fn1<T>
296 where f64: Cast<T>
297{
298 let _025: T = 0.25.cast();
299 let _4: T = 4.0.cast();
300 let _0: T = 0.0.cast();
301 let _05: T = 0.5.cast();
302 let _1: T = 1.0.cast();
303 let _075 = 0.75.cast();
304 return Arc::new(move |t| {
305 if t < _025 {a([_4 * t, _0])}
306 else if t < _05 {a([_1, _4 * (t - _025)])}
307 else if t < _075 {a([_1 - _4 * (t - _05), _1])}
308 else {a([_0, _1 - _4 * (t - _075)])}
309 })
310}
311
312pub fn margin1<T: Float>(m: T, a: Fn1<T>) -> Fn1<T>
314 where f64: Cast<T>
315{
316 let _1 = 1.0.cast();
317 let _2 = 2.0.cast();
318 let s = _1 / (_1 + _2 * m);
319 return Arc::new(move |t| a((t + m) * s))
320}
321
322pub fn margin2<T: Float>(m: T, a: Fn2<T>) -> Fn2<T>
324 where f64: Cast<T>
325{
326 let _1 = 1.0.cast();
327 let _2 = 2.0.cast();
328 let s = _1 / (_1 + _2 * m);
329 return Arc::new(move |t| a([(t[0] + m) * s, (t[1] + m) * s]))
330}
331
332pub fn margin3<T: Float>(m: T, a: Fn3<T>) -> Fn3<T>
334 where f64: Cast<T>
335{
336 let _1 = 1.0.cast();
337 let _2 = 2.0.cast();
338 let s = _1 / (_1 + _2 * m);
339 return Arc::new(move |t| a([(t[0] + m) * s, (t[1] + m) * s, (t[2] + m) * s]))
340}
341
342pub fn circle<T: Float>(center: [T; 3], radius: T) -> Fn2<T>
350 where f64: Cast<T>
351{
352 let two_pi = 6.283185307179586.cast();
353 return Arc::new(move |t| {
354 let angle = t[0] * two_pi;
355 [
356 center[0] + radius * t[1] * angle.cos(),
357 center[1] + radius * t[1] * angle.sin(),
358 center[2]
359 ]
360 })
361}
362
363pub fn sphere<T: Float>(center: [T; 3], radius: T) -> Fn3<T>
370 where f64: Cast<T>
371{
372 let two_pi = 6.283185307179586.cast();
373 let _1 = 1.0.cast();
374 let _2 = 2.0.cast();
375 return Arc::new(move |t| {
376 let angle0 = t[0] * two_pi;
377 let tx = _2 * t[1] - _1;
378 let rad = radius * (_1 - tx * tx).sqrt();
379 [
380 center[0] + rad * t[2] * angle0.cos(),
381 center[1] + rad * t[2] * angle0.sin(),
382 center[2] - radius + _2 * radius * t[1],
383 ]
384 })
385}
386
387pub fn x2<T: Float>(x: T, a: Fn2<T>) -> Fn1<T>
389 where f64: Cast<T>
390{
391 return Arc::new(move |t| a([x, t]))
392}
393
394pub fn y2<T: Float>(y: T, a: Fn2<T>) -> Fn1<T> {
396 return Arc::new(move |t| a([t, y]))
397}
398
399pub fn x3<T: Float>(x: T, a: Fn3<T>) -> Fn2<T> {
401 return Arc::new(move |t| a([x, t[0], t[1]]))
402}
403
404pub fn y3<T: Float>(y: T, a: Fn3<T>) -> Fn2<T> {
406 return Arc::new(move |t| a([t[0], y, t[1]]))
407}
408
409pub fn z3<T: Float>(z: T, a: Fn3<T>) -> Fn2<T> {
411 return Arc::new(move |t| a([t[0], t[1], z]))
412}
413
414pub fn ext1<T: Float>(a: Fn1<T>, b: Fn1<T>) -> Fn2<T> {
417 return Arc::new(move |t| add3(a(t[0]), b(t[1])))
418}
419
420pub fn ext2<T: Float>(a: Fn1<T>, b: Fn2<T>) -> Fn3<T> {
423 return Arc::new(move |t| add3(a(t[0]), b([t[1], t[2]])))
424}
425
426pub fn seg1<T: Float>(range: [T; 2], a: Fn1<T>) -> Fn1<T> {
428 return Arc::new(move |t| a(range[0] + (range[1] - range[0]) * t))
429}