use super::linspace;
pub fn heckbert(range: std::ops::Range<f64>, n: usize) -> Vec<f64> {
let d = nice_numbers(range.end - range.start, false);
let step = nice_numbers(d / (n - 1) as f64, true);
let min = (range.start / step).floor() * step;
let max = (range.end / step).ceil() * step;
linspace(min..max, step)
}
fn nice_numbers(x: f64, round: bool) -> f64 {
let e = x.log10().floor();
let ee = f64::powf(10.0, e);
let f = x / ee;
let nf = if round {
match f {
_ if f < 1.5 => 1.0,
_ if f < 3.0 => 2.0,
_ if f < 7.0 => 5.0,
_ => 10.0,
}
} else {
match f {
_ if f <= 1.0 => 1.0,
_ if f <= 2.0 => 2.0,
_ if f <= 5.0 => 5.0,
_ => 10.0,
}
};
nf * ee
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(nice_numbers(1.2, false), 2.0);
assert_eq!(nice_numbers(10.2, false), 20.0);
assert_eq!(nice_numbers(7.36, false), 10.0);
assert_eq!(
heckbert(-4.19..3.761, 5),
vec![-6.0, -4.0, -2.0, 0.0, 2.0, 4.0]
);
assert_eq!(heckbert(-4.19..3.761, 4), vec![-5.0, 0.0, 5.0]);
assert_eq!(heckbert(8.1..14.1, 4), vec![5.0, 10.0, 15.0]);
}
}