FunctionEntry: make newtons_method threshold smaller (fixes symbolicrepr) + prioritize special points

This commit is contained in:
Simon Gardling 2025-12-05 22:37:05 -05:00
parent f6a09fe449
commit 65ab0c6a1f
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D

View File

@ -344,7 +344,7 @@ impl FunctionEntry {
self.clear_integral();
}
let threshold: f64 = resolution / 2.0;
let threshold: f64 = f64::EPSILON;
let x_range = settings.min_x..settings.max_x;
// Calculates extrema
@ -377,7 +377,28 @@ impl FunctionEntry {
let step = (settings.max_x - settings.min_x) / (settings.plot_width as f64);
debug_assert!(step > 0.0);
// Plot back data
// Collect special points (extrema and roots) for exclusion from line hover detection
let special_points: Vec<&PlotPoint> = {
let mut points = Vec::new();
if settings.do_extrema {
points.extend(self.extrema_data.iter());
}
if settings.do_roots {
points.extend(self.root_data.iter());
}
points
};
// Helper to check if a point is near any special point
// Uses a radius in x-axis units based on the step size
let exclusion_radius = step * 3.0; // Exclude points within 3 steps of special points
let is_near_special_point = |p: &PlotPoint| -> bool {
special_points
.iter()
.any(|sp| (p.x - sp.x).abs() < exclusion_radius)
};
// Plot back data, filtering out points near special points for better hover detection
if !self.back_data.is_empty() {
if self.integral && (step >= integral_step) {
plot_ui.line(
@ -395,17 +416,32 @@ impl FunctionEntry {
.fill(0.0),
);
}
// Filter out points near special points so cursor snaps to them more easily
let filtered_back_data: Vec<PlotPoint> = self
.back_data
.iter()
.filter(|p| !is_near_special_point(p))
.cloned()
.collect();
plot_ui.line(
self.back_data
.clone()
filtered_back_data
.to_line()
.stroke(egui::Stroke::new(4.0, main_plot_color)),
);
}
// Plot derivative data
// Plot derivative data, also filtering near special points
if self.derivative && !self.derivative_data.is_empty() {
plot_ui.line(self.derivative_data.clone().to_line().color(Color32::GREEN));
let filtered_derivative_data: Vec<PlotPoint> = self
.derivative_data
.iter()
.filter(|p| !is_near_special_point(p))
.cloned()
.collect();
plot_ui.line(filtered_derivative_data.to_line().color(Color32::GREEN));
}
// Plot extrema points