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
use ndarray::Array2;
use num::complex::Complex64;
use num::traits::Pow;
use crate::utilities::luminance_to_rgba;
pub struct Wavefront {
pub values: Array2<Complex64>,
width: usize,
height: usize,
}
impl Wavefront {
pub fn new(values: Array2<Complex64>) -> Self {
Wavefront {
width: values.nrows(),
height: values.ncols(),
values,
}
}
pub fn rescale(&mut self, factor:f64) {
self.values = &self.values * factor;
}
pub fn intensities(&self) -> Array2<f64>{
self.values.mapv(
|comval| (comval).norm().pow(2)
)
}
pub fn save_image(&self, path: &str) -> () {
let intensities = Self::intensities(&self);
let rgba = luminance_to_rgba(intensities.into_raw_vec());
let img: Vec<u8> = rgba.iter().map(|val| *val as u8).collect();
image::save_buffer(path, &img, self.width as u32, self.height as u32, image::ColorType::Rgba8).unwrap();
}
}
#[cfg(test)]
mod tests {
use assert_approx_eq::assert_approx_eq;
use crate::wavefront::Wavefront;
use num::traits::Pow;
use ndarray::arr2;
use num::complex::Complex64;
#[test]
fn complex_to_intensities() {
let my_wavefront = Wavefront::new( arr2(&[[Complex64::new(5., 1.),
Complex64::new(0., 0.)],
[Complex64::new(0., 0.),
Complex64::new(4., 2.)]]));
let analytic_answers = vec![5f64.pow(2) + 1f64.pow(2), 0., 0.,
4f64.pow(2) + 2f64.pow(2)];
for (i, intensity) in my_wavefront.intensities().iter().enumerate() {
assert_approx_eq!(intensity, analytic_answers[i])
}
}
}