mod path_builder;
mod validation;
use crate::errors::SmoothError;
use crate::output::path::SmoothPath;
use crate::types::Point;
use crate::utils::clamp01;
use path_builder::build_smooth_frame_path;
use validation::validate_frame;
#[derive(Debug, Clone, PartialEq)]
pub struct SmoothFrame {
points: Vec<Point>,
radius: f64,
smoothing: f64,
}
impl SmoothFrame {
#[must_use]
pub fn closed(points: impl IntoIterator<Item = Point>) -> Self {
Self {
points: points.into_iter().collect(),
radius: 0.0,
smoothing: 0.0,
}
}
#[must_use]
pub fn with_radius(mut self, radius: f64) -> Self {
self.radius = radius;
self
}
#[must_use]
pub fn with_smoothing(mut self, smoothing: f64) -> Self {
self.smoothing = smoothing;
self
}
#[must_use]
pub fn points(&self) -> &[Point] {
&self.points
}
pub fn to_path(&self) -> Result<SmoothPath, SmoothError> {
validate_frame(&self.points)?;
if self.radius < 0.0 {
return Err(SmoothError::NegativeInput);
}
if !self.radius.is_finite() || !self.smoothing.is_finite() {
return Err(SmoothError::NonFiniteInput);
}
Ok(build_smooth_frame_path(
&self.points,
self.radius,
clamp01(self.smoothing),
))
}
}