#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Band {
count: usize,
start: f64,
step: f64,
bandwidth: f64,
}
const PADDING: f64 = 0.25;
impl Band {
pub fn new(count: usize, range: (f64, f64)) -> Band {
let span = (range.1 - range.0).max(0.0);
let steps = count as f64 + PADDING;
let step = if count == 0 { 0.0 } else { span / steps };
Band {
count,
start: range.0 + step * PADDING,
step,
bandwidth: step * (1.0 - PADDING),
}
}
pub fn count(&self) -> usize {
self.count
}
pub fn bandwidth(&self) -> f64 {
self.bandwidth
}
pub fn step(&self) -> f64 {
self.step
}
pub fn position(&self, index: usize) -> f64 {
self.start + self.step * index as f64
}
pub fn center(&self, index: usize) -> f64 {
self.position(index) + self.bandwidth / 2.0
}
pub fn index_at(&self, position: f64) -> Option<usize> {
if self.count == 0 || self.step <= 0.0 {
return None;
}
let offset = position - self.start;
if offset < 0.0 {
return None;
}
let index = (offset / self.step).floor();
let within = offset - index * self.step;
let index = index as usize;
(index < self.count && within < self.bandwidth).then_some(index)
}
}
#[cfg(test)]
#[path = "tests/band_tests.rs"]
mod tests;