1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use num::{Float, NumCast};
use num::PrimInt as Int;
use std::mem;
#[inline]
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
if val < min { min } else { if val > max { max } else { val } }
}
#[inline]
pub fn fmod<F: Float>(numer: F, denom: F) -> F {
let rquot: F = (numer / denom).floor();
numer - rquot * denom
}
#[inline]
pub fn in_range<T: Ord>(val: T, min: T, max: T) -> bool {
val >= min && val <= max
}
#[inline]
pub fn lerp<F: Float>(start: F, stop: F, amt: F) -> F {
start + (stop - start) * amt
}
#[inline]
pub fn map_range<X, Y>(val: X, in_min: X, in_max: X, out_min: Y, out_max: Y) -> Y where
X: NumCast,
Y: NumCast + Copy,
{
use epsilon::epsilon;
let val_f: f64 = NumCast::from(val).unwrap();
let in_min_f: f64 = NumCast::from(in_min).unwrap();
let in_max_f: f64 = NumCast::from(in_max).unwrap();
let out_min_f: f64 = NumCast::from(out_min).unwrap();
let out_max_f: f64 = NumCast::from(out_max).unwrap();
if (in_min_f - in_max_f).abs() < epsilon() {
println!("utils::math::map_range warning: avoiding possible divide by zero, \
in_min ({}) and in_max({})", in_min_f, in_max_f);
return out_min;
}
Y::from((val_f - in_min_f) / (in_max_f - in_min_f) * (out_max_f - out_min_f) + out_min_f)
.unwrap()
}
#[inline]
pub fn remainder<F: Float>(numer: F, denom: F) -> F {
let rquot: F = (numer / denom).round();
numer - rquot * denom
}
#[inline]
pub fn modulo<I: Int>(a: I, b: I) -> I {
match a % b {
r if (r > I::zero() && b < I::zero())
|| (r < I::zero() && b > I::zero()) => (r + b),
r => r,
}
}
#[inline]
pub fn wrap<F: Float>(val: F, mut from: F, mut to: F) -> F {
if from > to { mem::swap(&mut from, &mut to); }
let cycle = to - from;
if cycle == F::zero() { return to; }
val - cycle * ((val - from) / cycle).floor()
}
#[inline]
pub fn sigmoid<F: Float>(f: F) -> F {
use std::f64::consts::E;
let e = F::from(E).unwrap();
F::one() / (F::one() + e.powf(-f))
}