Skip to main content

smooth_frame/input/frame/
mod.rs

1mod path_builder;
2mod validation;
3
4use crate::errors::SmoothError;
5use crate::output::path::SmoothPath;
6use crate::types::Point;
7use crate::utils::clamp01;
8
9use path_builder::build_smooth_frame_path;
10use validation::validate_frame;
11
12/// 闭合凸 polygon / frame。
13#[derive(Debug, Clone, PartialEq)]
14pub struct SmoothFrame {
15    points: Vec<Point>,
16    radius: f64,
17    smoothing: f64,
18}
19
20impl SmoothFrame {
21    /// 创建闭合 frame。
22    ///
23    /// 当前版本要求输入点组成非退化凸多边形。
24    #[must_use]
25    pub fn closed(points: impl IntoIterator<Item = Point>) -> Self {
26        Self {
27            points: points.into_iter().collect(),
28            radius: 0.0,
29            smoothing: 0.0,
30        }
31    }
32
33    /// 设置每个角的核心圆半径。
34    #[must_use]
35    pub fn with_radius(mut self, radius: f64) -> Self {
36        self.radius = radius;
37        self
38    }
39
40    /// 设置每个角的 Sketch-like smoothing,生成前会 clamp 到 `[0, 1]`。
41    #[must_use]
42    pub fn with_smoothing(mut self, smoothing: f64) -> Self {
43        self.smoothing = smoothing;
44        self
45    }
46
47    /// 返回 frame 输入点。
48    #[must_use]
49    pub fn points(&self) -> &[Point] {
50        &self.points
51    }
52
53    /// 生成闭合 smooth frame 路径。
54    pub fn to_path(&self) -> Result<SmoothPath, SmoothError> {
55        validate_frame(&self.points)?;
56
57        if self.radius < 0.0 {
58            return Err(SmoothError::NegativeInput);
59        }
60        if !self.radius.is_finite() || !self.smoothing.is_finite() {
61            return Err(SmoothError::NonFiniteInput);
62        }
63
64        Ok(build_smooth_frame_path(
65            &self.points,
66            self.radius,
67            clamp01(self.smoothing),
68        ))
69    }
70}