From 1a1f2456227e74d6c3b140470976a13d5ae0a27f Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 25 Feb 2022 20:59:40 -0500 Subject: [PATCH] dynamic plotting resolution --- src/egui_app.rs | 7 +++++-- src/function.rs | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/egui_app.rs b/src/egui_app.rs index 83eff2a..4da444d 100644 --- a/src/egui_app.rs +++ b/src/egui_app.rs @@ -44,6 +44,7 @@ impl Default for MathApp { String::from(DEFAULT_FUNCION), def_min_x, def_max_x, + 100, true, Some(def_min_x), Some(def_max_x), @@ -111,6 +112,7 @@ impl epi::App for MathApp { // min_x and max_x will be updated later, doesn't matter here functions.push(Function::new(String::from(DEFAULT_FUNCION), -1.0, 1.0, + 100, false, None, None, @@ -199,6 +201,7 @@ impl epi::App for MathApp { ui.label(format!("Error: {}", parse_error)); return; } + let available_width: usize = ui.available_width() as usize; let step = self.get_step(); let mut area_list: Vec = Vec::new(); @@ -211,10 +214,10 @@ impl epi::App for MathApp { let bounds = plot_ui.plot_bounds(); let minx_bounds: f64 = bounds.min()[0]; let maxx_bounds: f64 = bounds.max()[0]; - // println!("({}, {})", minx_bounds, maxx_bounds); for (i, function) in self.functions.iter_mut().enumerate() { - function.update_bounds(minx_bounds, maxx_bounds); + function.update_bounds(minx_bounds, maxx_bounds, available_width); + if self.func_strs[i].is_empty() { continue; } diff --git a/src/function.rs b/src/function.rs index bc31171..4d19111 100644 --- a/src/function.rs +++ b/src/function.rs @@ -3,8 +3,6 @@ use egui::plot::Value; use egui::widgets::plot::Bar; use meval::Expr; -pub const RESOLUTION: f64 = 1000.0; - // Struct that stores and manages the output of a function pub struct FunctionOutput { // The actual line graph @@ -43,6 +41,7 @@ pub struct Function { pub(crate) func_str: String, min_x: f64, max_x: f64, + pixel_width: usize, back_cache: Cache>, front_cache: Cache<(Vec, f64)>, @@ -55,7 +54,7 @@ pub struct Function { impl Function { pub fn new( - func_str: String, min_x: f64, max_x: f64, integral: bool, integral_min_x: Option, + func_str: String, min_x: f64, max_x: f64, pixel_width: usize, integral: bool, integral_min_x: Option, integral_max_x: Option, integral_num: Option, ) -> Self { // Makes sure proper arguments are passed when integral is enabled @@ -76,6 +75,7 @@ impl Function { func_str, min_x, max_x, + pixel_width, back_cache: Cache::new_empty(), front_cache: Cache::new_empty(), integral, @@ -114,6 +114,7 @@ impl Function { func_str, self.min_x, self.max_x, + self.pixel_width, integral, integral_min_x, integral_max_x, @@ -148,12 +149,12 @@ impl Function { } } - #[inline] - pub fn update_bounds(&mut self, min_x: f64, max_x: f64) { - if (min_x != self.min_x) | (max_x != self.max_x) { + pub fn update_bounds(&mut self, min_x: f64, max_x: f64, pixel_width: usize) { + if (min_x != self.min_x) | (max_x != self.max_x) | (pixel_width != self.pixel_width) { self.back_cache.invalidate(); self.min_x = min_x; self.max_x = max_x; + self.pixel_width = pixel_width; } } @@ -170,10 +171,14 @@ impl Function { let front_values: Vec = match self.back_cache.is_valid() { false => { let absrange = (self.max_x - self.min_x).abs(); - let front_data: Vec<(f64, f64)> = (1..=(RESOLUTION as usize)) - .map(|x| ((x as f64 / RESOLUTION) * absrange) + self.min_x) + let resolution: f64 = (self.pixel_width as f64/absrange) as f64; + let front_data: Vec<(f64, f64)> = (1..=self.pixel_width) + .map(|x| ((x as f64 / resolution as f64)) + self.min_x) + // .step_by() .map(|x| (x, self.run_func(x))) .collect(); + // println!("{} {}", front_data.len(), front_data.len() as f64/absrange); + let output: Vec = front_data.iter().map(|(x, y)| Value::new(*x, *y)).collect(); self.back_cache.set(output.clone());