aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-01-21 17:25:43 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2024-01-21 17:25:43 +0100
commit79554285331846db8a1d06e2570d5acbb2f2690e (patch)
treecf590a0caf22eabf1809a8d43992ac11128b75a0
parentb9b32972afda261020dd207b4ea2b44b7b697b83 (diff)
implement dynamic graph removal and pushing
-rw-r--r--src/function_cache.rs4
-rw-r--r--src/math/context.rs8
-rw-r--r--src/math/expression_function.rs2
-rw-r--r--src/ui/graph.rs31
4 files changed, 36 insertions, 9 deletions
diff --git a/src/function_cache.rs b/src/function_cache.rs
index d4beb16..edd7001 100644
--- a/src/function_cache.rs
+++ b/src/function_cache.rs
@@ -29,4 +29,8 @@ impl FunctionCache {
v
}
}
+
+ pub fn name(&self) -> &str {
+ self.func.name()
+ }
}
diff --git a/src/math/context.rs b/src/math/context.rs
index cb0bca0..e23b96f 100644
--- a/src/math/context.rs
+++ b/src/math/context.rs
@@ -58,6 +58,14 @@ impl Context {
pub fn function(&self, name: &str) -> Option<&Arc<dyn Function>> {
self.funcs.get(name)
}
+
+ pub fn remove_variable(&mut self, name: &str) {
+ self.vars.remove(name);
+ }
+
+ pub fn remove_function(&mut self, name: &str) {
+ self.funcs.remove(name);
+ }
}
#[macro_export]
diff --git a/src/math/expression_function.rs b/src/math/expression_function.rs
index b9a480f..9debdc4 100644
--- a/src/math/expression_function.rs
+++ b/src/math/expression_function.rs
@@ -9,7 +9,7 @@ use crate::math::{
function::{Function, FunctionArgument, EmptyFunction}
};
-#[derive(Default)]
+#[derive(Default, Clone)]
pub struct ExpressionFunction {
expr: Expression,
name: String,
diff --git a/src/ui/graph.rs b/src/ui/graph.rs
index 83d90f8..14f0c7d 100644
--- a/src/ui/graph.rs
+++ b/src/ui/graph.rs
@@ -36,6 +36,7 @@ impl GraphCanvas {
pub fn push(&mut self, f: &str) {
if let Ok(f) = ExpressionFunction::from_string(f.to_string(), self.ctx.operations()) {
+ self.ctx.set_function(f.name(), std::sync::Arc::new(f.clone()));
self.funcs.lock().unwrap().push(Some(FunctionCache::new(f)));
} else {
self.funcs.lock().unwrap().push(None);
@@ -43,15 +44,28 @@ impl GraphCanvas {
}
pub fn set(&mut self, i: usize, f: &str) {
- if let Ok(f) = ExpressionFunction::from_string(f.to_string(), self.ctx.operations()) {
- self.funcs.lock().unwrap()[i] = Some(FunctionCache::new(f));
- } else {
- self.funcs.lock().unwrap().push(None);
+ if let Ok(mut vf) = self.funcs.lock() {
+ if let Some(last_f) = &vf[i] {
+ self.ctx.remove_function(last_f.name());
+ }
+
+ if let Ok(f) = ExpressionFunction::from_string(f.to_string(), self.ctx.operations()) {
+ self.ctx.set_function(f.name(), std::sync::Arc::new(f.clone()));
+ vf[i] = Some(FunctionCache::new(f));
+ } else {
+ vf[i] = None;
+ }
+
}
}
pub fn remove(&mut self, i: usize) {
- self.funcs.lock().unwrap().remove(i);
+ if let Ok(mut vf) = self.funcs.lock() {
+ if let Some(f) = &vf[i] {
+ self.ctx.remove_function(f.name());
+ }
+ vf.remove(i);
+ }
}
}
@@ -220,10 +234,11 @@ impl canvas::Program<Message, Renderer> for GraphCanvas {
{
let mut y1 = func.eval(Complex::new(rect.x as f64, 0.0), &self.ctx).real as f32;
for x in (rect.x as i64..(rect.x + rect.width) as i64).step_by(step) {
- for d in 0..10 {
- let d = d as f32 / 10.0;
+ let precision = state.scale as i64;
+ for d in 0..precision {
+ let d = d as f32 / (precision as f32);
let x1 = x as f32 + d * step as f32;
- let x2 = x as f32 + (d + 0.1) * step as f32;
+ let x2 = x as f32 + (d + (1.0 / precision as f32)) * step as f32;
let y2 = func.eval(Complex::new(x2 as f64, 0.0), &self.ctx).real as f32;
if y1.is_finite() && !y1.is_nan() && y2.is_finite() && !y2.is_nan() {
let line =