dynamic plotting resolution

This commit is contained in:
Simon Gardling 2022-02-25 20:59:40 -05:00
parent d7632cc11e
commit 1a1f245622
2 changed files with 18 additions and 10 deletions

View File

@ -44,6 +44,7 @@ impl Default for MathApp {
String::from(DEFAULT_FUNCION), String::from(DEFAULT_FUNCION),
def_min_x, def_min_x,
def_max_x, def_max_x,
100,
true, true,
Some(def_min_x), Some(def_min_x),
Some(def_max_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 // min_x and max_x will be updated later, doesn't matter here
functions.push(Function::new(String::from(DEFAULT_FUNCION), -1.0, functions.push(Function::new(String::from(DEFAULT_FUNCION), -1.0,
1.0, 1.0,
100,
false, false,
None, None,
None, None,
@ -199,6 +201,7 @@ impl epi::App for MathApp {
ui.label(format!("Error: {}", parse_error)); ui.label(format!("Error: {}", parse_error));
return; return;
} }
let available_width: usize = ui.available_width() as usize;
let step = self.get_step(); let step = self.get_step();
let mut area_list: Vec<f64> = Vec::new(); let mut area_list: Vec<f64> = Vec::new();
@ -211,10 +214,10 @@ impl epi::App for MathApp {
let bounds = plot_ui.plot_bounds(); let bounds = plot_ui.plot_bounds();
let minx_bounds: f64 = bounds.min()[0]; let minx_bounds: f64 = bounds.min()[0];
let maxx_bounds: f64 = bounds.max()[0]; let maxx_bounds: f64 = bounds.max()[0];
// println!("({}, {})", minx_bounds, maxx_bounds);
for (i, function) in self.functions.iter_mut().enumerate() { 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() { if self.func_strs[i].is_empty() {
continue; continue;
} }

View File

@ -3,8 +3,6 @@ use egui::plot::Value;
use egui::widgets::plot::Bar; use egui::widgets::plot::Bar;
use meval::Expr; use meval::Expr;
pub const RESOLUTION: f64 = 1000.0;
// Struct that stores and manages the output of a function // Struct that stores and manages the output of a function
pub struct FunctionOutput { pub struct FunctionOutput {
// The actual line graph // The actual line graph
@ -43,6 +41,7 @@ pub struct Function {
pub(crate) func_str: String, pub(crate) func_str: String,
min_x: f64, min_x: f64,
max_x: f64, max_x: f64,
pixel_width: usize,
back_cache: Cache<Vec<Value>>, back_cache: Cache<Vec<Value>>,
front_cache: Cache<(Vec<Bar>, f64)>, front_cache: Cache<(Vec<Bar>, f64)>,
@ -55,7 +54,7 @@ pub struct Function {
impl Function { impl Function {
pub fn new( pub fn new(
func_str: String, min_x: f64, max_x: f64, integral: bool, integral_min_x: Option<f64>, func_str: String, min_x: f64, max_x: f64, pixel_width: usize, integral: bool, integral_min_x: Option<f64>,
integral_max_x: Option<f64>, integral_num: Option<usize>, integral_max_x: Option<f64>, integral_num: Option<usize>,
) -> Self { ) -> Self {
// Makes sure proper arguments are passed when integral is enabled // Makes sure proper arguments are passed when integral is enabled
@ -76,6 +75,7 @@ impl Function {
func_str, func_str,
min_x, min_x,
max_x, max_x,
pixel_width,
back_cache: Cache::new_empty(), back_cache: Cache::new_empty(),
front_cache: Cache::new_empty(), front_cache: Cache::new_empty(),
integral, integral,
@ -114,6 +114,7 @@ impl Function {
func_str, func_str,
self.min_x, self.min_x,
self.max_x, self.max_x,
self.pixel_width,
integral, integral,
integral_min_x, integral_min_x,
integral_max_x, integral_max_x,
@ -148,12 +149,12 @@ impl Function {
} }
} }
#[inline] pub fn update_bounds(&mut self, min_x: f64, max_x: f64, pixel_width: usize) {
pub fn update_bounds(&mut self, min_x: f64, max_x: f64) { if (min_x != self.min_x) | (max_x != self.max_x) | (pixel_width != self.pixel_width) {
if (min_x != self.min_x) | (max_x != self.max_x) {
self.back_cache.invalidate(); self.back_cache.invalidate();
self.min_x = min_x; self.min_x = min_x;
self.max_x = max_x; self.max_x = max_x;
self.pixel_width = pixel_width;
} }
} }
@ -170,10 +171,14 @@ impl Function {
let front_values: Vec<Value> = match self.back_cache.is_valid() { let front_values: Vec<Value> = match self.back_cache.is_valid() {
false => { false => {
let absrange = (self.max_x - self.min_x).abs(); let absrange = (self.max_x - self.min_x).abs();
let front_data: Vec<(f64, f64)> = (1..=(RESOLUTION as usize)) let resolution: f64 = (self.pixel_width as f64/absrange) as f64;
.map(|x| ((x as f64 / RESOLUTION) * absrange) + self.min_x) 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))) .map(|x| (x, self.run_func(x)))
.collect(); .collect();
// println!("{} {}", front_data.len(), front_data.len() as f64/absrange);
let output: Vec<Value> = let output: Vec<Value> =
front_data.iter().map(|(x, y)| Value::new(*x, *y)).collect(); front_data.iter().map(|(x, y)| Value::new(*x, *y)).collect();
self.back_cache.set(output.clone()); self.back_cache.set(output.clone());