1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: MIT |
3 | |
4 | use plotters::prelude::*; |
5 | use slint::SharedPixelBuffer; |
6 | |
7 | #[cfg (target_arch = "wasm32" )] |
8 | use wasm_bindgen::prelude::*; |
9 | |
10 | #[cfg (target_arch = "wasm32" )] |
11 | mod wasm_backend; |
12 | |
13 | slint::slint! { |
14 | import { MainWindow } from "plotter.slint" ; |
15 | } |
16 | |
17 | fn pdf(x: f64, y: f64, a: f64) -> f64 { |
18 | const SDX: f64 = 0.1; |
19 | const SDY: f64 = 0.1; |
20 | let x: f64 = x as f64 / 10.0; |
21 | let y: f64 = y as f64 / 10.0; |
22 | a * (-x * x / 2.0 / SDX / SDX - y * y / 2.0 / SDY / SDY).exp() |
23 | } |
24 | |
25 | fn render_plot(pitch: f32, yaw: f32, amplitude: f32) -> slint::Image { |
26 | let mut pixel_buffer = SharedPixelBuffer::new(640, 480); |
27 | let size = (pixel_buffer.width(), pixel_buffer.height()); |
28 | |
29 | let backend = BitMapBackend::with_buffer(pixel_buffer.make_mut_bytes(), size); |
30 | |
31 | // Plotters requires TrueType fonts from the file system to draw axis text - we skip that for |
32 | // WASM for now. |
33 | #[cfg (target_arch = "wasm32" )] |
34 | let backend = wasm_backend::BackendWithoutText { backend }; |
35 | |
36 | let root = backend.into_drawing_area(); |
37 | |
38 | root.fill(&WHITE).expect("error filling drawing area" ); |
39 | |
40 | let mut chart = ChartBuilder::on(&root) |
41 | .build_cartesian_3d(-3.0..3.0, 0.0..6.0, -3.0..3.0) |
42 | .expect("error building coordinate system" ); |
43 | chart.with_projection(|mut p| { |
44 | p.pitch = pitch as f64; |
45 | p.yaw = yaw as f64; |
46 | p.scale = 0.7; |
47 | p.into_matrix() // build the projection matrix |
48 | }); |
49 | |
50 | chart.configure_axes().draw().expect("error drawing" ); |
51 | |
52 | chart |
53 | .draw_series( |
54 | SurfaceSeries::xoz( |
55 | (-15..=15).map(|x| x as f64 / 5.0), |
56 | (-15..=15).map(|x| x as f64 / 5.0), |
57 | |x, y| pdf(x, y, amplitude as f64), |
58 | ) |
59 | .style_func(&|&v| { |
60 | (&HSLColor(240.0 / 360.0 - 240.0 / 360.0 * v / 5.0, 1.0, 0.7)).into() |
61 | }), |
62 | ) |
63 | .expect("error drawing series" ); |
64 | |
65 | root.present().expect("error presenting" ); |
66 | drop(chart); |
67 | drop(root); |
68 | |
69 | slint::Image::from_rgb8(pixel_buffer) |
70 | } |
71 | |
72 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen(start))] |
73 | pub fn main() { |
74 | // This provides better error messages in debug mode. |
75 | // It's disabled in release mode so it doesn't bloat up the file size. |
76 | #[cfg (all(debug_assertions, target_arch = "wasm32" ))] |
77 | console_error_panic_hook::set_once(); |
78 | |
79 | let main_window = MainWindow::new().unwrap(); |
80 | |
81 | main_window.on_render_plot(render_plot); |
82 | |
83 | main_window.run().unwrap(); |
84 | } |
85 | |