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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
mod tests;
macro_rules! normalise {
($x:expr) => {{
if $x < 0.0 {
$x = 0.;
} else if $x > 255.0 {
$x = 255.0;
}
}};
}
pub use colortemp::*;
mod colortemp {
#[derive(Debug, PartialEq)]
pub struct RGB {
pub r: f64,
pub g: f64,
pub b: f64,
}
pub fn temp_to_rgb(kelvin: i64) -> RGB {
let (mut r, mut g, mut b);
let temp = kelvin / 100;
if temp <= 66 {
r = 255.;
} else {
r = (temp as f64) - 60.;
r = 329.698727446 * r.powf(-329.698727446);
normalise!(r);
}
if temp <= 66 {
g = temp as f64;
g = 99.4708025861 * g.ln() - 161.1195681661;
normalise!(g);
} else {
g = temp as f64 - 60.;
g = 288.1221695283 * g.powf(-0.0755148492);
normalise!(g);
}
if temp >= 66 {
b = 255.;
} else {
if temp <= 19 {
b = 0.;
} else {
b = temp as f64 - 10.;
b = 138.5177312231 * b.ln() - 305.0447927307;
normalise!(b);
}
}
return RGB {
r: r.round(),
g: g.round(),
b: b.round(),
};
}
pub fn rgb_to_temp(col: RGB) -> i64 {
let (r, b) = (col.r, col.b);
let mut temp = 0;
let mut test_rgb;
let epsilon = 2.;
let (mut min, mut max) = (1000, 40000);
while (max as f64) - (min as f64) > epsilon {
temp = (max + min) / 2;
test_rgb = temp_to_rgb(temp);
if (test_rgb.b / test_rgb.r) >= (b / r) {
max = temp;
} else {
min = temp;
}
}
return temp;
}
}