This commit is contained in:
Simon Gardling 2022-03-09 21:15:12 -05:00
parent 99592915e1
commit 232f470ce1
3 changed files with 42 additions and 2 deletions

View File

@ -8,10 +8,10 @@
- Non `y=` functions. - Non `y=` functions.
3. Smart display of graph 3. Smart display of graph
- Display of intersections between functions - Display of intersections between functions
- Display of roots
4. Fix integral line 4. Fix integral line
5. re-add euler's number (well it works if you use capital e like `E^x`) 5. re-add euler's number (well it works if you use capital e like `E^x`)
6. allow constants in min/max integral input (like pi or euler's number) 6. allow constants in min/max integral input (like pi or euler's number)
7. sliding values for functions (like a user-interactable slider that adjusts a variable in the function, like desmos) 7. sliding values for functions (like a user-interactable slider that adjusts a variable in the function, like desmos)
8. Keybinds 8. Keybinds
9. nth derivative support (again) 9. nth derivative support (again)
10. add configs for toggling display of roots and extrema

View File

@ -276,6 +276,33 @@ impl FunctionEntry {
self self
} }
// Finds roots
fn roots(&mut self) {
let mut root_list: Vec<Value> = Vec::new();
let mut last_ele: Option<Value> = None;
for ele in self.output.back.as_ref().unwrap().iter() {
if last_ele.is_none() {
last_ele = Some(*ele);
continue;
}
if last_ele.unwrap().y.signum() != ele.y.signum() {
// Do 10 iterations of newton's method, should be more than accurate
let x = {
let mut x1: f64 = last_ele.unwrap().x;
for _ in 0..10 {
x1 = last_ele.unwrap().x
- (self.function.get(x1) / self.function.derivative(x1))
}
x1
};
root_list.push(Value::new(x, self.function.get(x)));
}
last_ele = Some(*ele);
}
self.output.roots = Some(root_list);
}
// Finds extrema // Finds extrema
fn extrema(&mut self) { fn extrema(&mut self) {
let mut extrama_list: Vec<Value> = Vec::new(); let mut extrama_list: Vec<Value> = Vec::new();
@ -309,6 +336,7 @@ impl FunctionEntry {
self.output.integral = integral; self.output.integral = integral;
self.output.derivative = derivative; self.output.derivative = derivative;
self.extrema(); self.extrema();
self.roots();
self.output.display( self.output.display(
plot_ui, plot_ui,

View File

@ -14,6 +14,7 @@ pub struct FunctionOutput {
pub(crate) integral: Option<(Vec<Bar>, f64)>, pub(crate) integral: Option<(Vec<Bar>, f64)>,
pub(crate) derivative: Option<Vec<Value>>, pub(crate) derivative: Option<Vec<Value>>,
pub(crate) extrema: Option<Vec<Value>>, pub(crate) extrema: Option<Vec<Value>>,
pub(crate) roots: Option<Vec<Value>>,
} }
impl FunctionOutput { impl FunctionOutput {
@ -23,6 +24,7 @@ impl FunctionOutput {
integral: None, integral: None,
derivative: None, derivative: None,
extrema: None, extrema: None,
roots: None,
} }
} }
@ -31,6 +33,7 @@ impl FunctionOutput {
self.integral = None; self.integral = None;
self.derivative = None; self.derivative = None;
self.extrema = None; self.extrema = None;
self.roots = None;
} }
pub fn invalidate_back(&mut self) { self.back = None; } pub fn invalidate_back(&mut self) { self.back = None; }
@ -68,6 +71,15 @@ impl FunctionOutput {
); );
} }
if let Some(roots_data) = self.roots.clone() {
plot_ui.points(
Points::new(Values::from_values(roots_data))
.color(Color32::LIGHT_BLUE)
.name("Root")
.radius(5.0),
);
}
if let Some(integral_data) = self.integral.clone() { if let Some(integral_data) = self.integral.clone() {
plot_ui.bar_chart( plot_ui.bar_chart(
BarChart::new(integral_data.0) BarChart::new(integral_data.0)