| 99 let τ = 0.05; |
99 let τ = 0.05; |
| 100 |
100 |
| 101 std::fs::create_dir_all(PREFIX)?; |
101 std::fs::create_dir_all(PREFIX)?; |
| 102 for face in Face::all() { |
102 for face in Face::all() { |
| 103 write_face_csv(format!("{PREFIX}/{face}"), face, 32, |x| f.apply(x) + g.apply(x))?; |
103 write_face_csv(format!("{PREFIX}/{face}"), face, 32, |x| f.apply(x) + g.apply(x))?; |
| 104 write_face_img(format!("{PREFIX}/{face}"), face, 128, |x| f.apply(x) + g.apply(x))?; |
104 } |
| 105 } |
105 write_face_imgs(128, |x| f.apply(x) + g.apply(x))?; |
| 106 |
106 |
| 107 run_and_save("x1", &f, &g, OnCube::new(F3, Loc([0.1, 0.7])), τ)?; |
107 run_and_save("x1", &f, &g, OnCube::new(F3, Loc([0.1, 0.7])), τ)?; |
| 108 run_and_save("x2", &f, &g, OnCube::new(F2, Loc([0.1, 0.7])), τ)?; |
108 run_and_save("x2", &f, &g, OnCube::new(F2, Loc([0.1, 0.7])), τ)?; |
| 109 run_and_save("x3", &f, &g, OnCube::new(F6, Loc([0.6, 0.2])), τ) |
109 run_and_save("x3", &f, &g, OnCube::new(F6, Loc([0.6, 0.2])), τ) |
| 110 } |
110 } |
| 143 Ok(()) |
143 Ok(()) |
| 144 } |
144 } |
| 145 |
145 |
| 146 /// Writes the values of `f` on `face` of a [`OnCube`] into a PNG file |
146 /// Writes the values of `f` on `face` of a [`OnCube`] into a PNG file |
| 147 /// with resolution `n × n`. |
147 /// with resolution `n × n`. |
| 148 fn write_face_img(filename : String, face : Face, n : usize, mut f : impl FnMut(&OnCube) -> f64) -> DynError { |
148 fn write_face_imgs(n : usize, mut f : impl FnMut(&OnCube) -> f64) -> DynError { |
| 149 let mut img = ImageBuffer::new(n as u32, n as u32); |
|
| 150 let grid = LinSpace { |
149 let grid = LinSpace { |
| 151 start : Loc([0.0, 0.0]), |
150 start : Loc([0.0, 0.0]), |
| 152 end : Loc([1.0, 1.0]), |
151 end : Loc([1.0, 1.0]), |
| 153 count : [n, n] |
152 count : [n, n] |
| 154 }; |
153 }; |
| 155 let rawdata : Vec<_> = grid.into_iter() |
154 |
| 156 .map(|x| f(&OnCube::new(face, x))) |
155 let mut m = 0.0; |
| 157 .collect(); |
156 let mut datas = Vec::new(); |
| 158 let a = rawdata.iter().copied().reduce(f64::max).unwrap(); |
157 |
| 159 img.pixels_mut() |
158 for face in Face::all() { |
| 160 .zip(rawdata) |
159 let rawdata : Vec<_> = grid.into_iter() |
| 161 .for_each(|(p, v)| { |
160 .map(|Loc([x,y])| f(&OnCube::new(face, Loc([x, 1.0-y])))) |
| 162 let t = v/a; |
161 .collect(); |
| 163 let rgb = [1.0-t, 1.0-t, 1.0]; |
162 m = rawdata.iter().copied().fold(m, f64::max); |
| 164 *p = Rgb(rgb.map(|v| (v*(u8::RANGE_MAX as f64)) as u8)) |
163 datas.push((face, rawdata)); |
| 165 }); |
164 } |
| 166 |
165 |
| 167 img.save_with_format(format!("{filename}.png"), ImageFormat::Png)?; |
166 for (face, rawdata) in datas { |
| |
167 let mut img = ImageBuffer::new(n as u32, n as u32); |
| |
168 img.pixels_mut() |
| |
169 .zip(rawdata) |
| |
170 .for_each(|(p, v)| { |
| |
171 let t = v/m; |
| |
172 // A very colourful option for bug hunting. |
| |
173 //let rgb = [(50.0*t).cos(), (20.0*t).sin(), (3.0*t).cos()]; |
| |
174 let rgb = [1.0-t, 1.0-t, 1.0]; |
| |
175 *p = Rgb(rgb.map(|v| (v*(u8::RANGE_MAX as f64)) as u8)) |
| |
176 }); |
| |
177 |
| |
178 img.save_with_format(format!("{PREFIX}/{face}.png"), ImageFormat::Png)?; |
| |
179 } |
| 168 |
180 |
| 169 Ok(()) |
181 Ok(()) |
| 170 } |
182 } |
| 171 |
183 |
| 172 /// Writes the values of `f` on `face` of a [`OnCube`] into a CSV file |
184 /// Writes the values of `f` on `face` of a [`OnCube`] into a CSV file |