#quadratic #cubic #bezier #conic #curve-conversion

cucoqu

cucoqu是一个用于在不同类型的贝塞尔样条之间转换的Rust库。目前它只支持在类型设计和绘制曲线中最常用的类型:cubic贝塞尔曲线,quadratic贝塞尔曲线,以及一种有理贝塞尔曲线:conic贝塞尔曲线。

1个不稳定版本

0.1.0 2022年12月19日

#902 in 算法

Apache-2.0

165KB
861

cucoqu — 三次 ← 圆锥 ← 二次

阅读日语版

© 2022 Fredrick R. Brennan, MFEK作者,Skia作者,以及GPT-3huh?

cucoqu是一个用于在不同类型的贝塞尔样条之间转换的Rust库。目前它只支持在类型设计和绘制曲线中最常用的类型:cubic贝塞尔曲线,quadratic贝塞尔曲线,以及一种有理贝塞尔曲线:conic贝塞尔曲线。

此库取代了MFEK中许多对Skia的C++代码的调用,并替换了其点类型之间的转换。

待办事项

  • 任意提高n次贝塞尔段的多项式次数

API

类型

三次

// Bézier segments
/// A cubic [`Bezier` segment][cubic-bezier].
///
/// [cubic-bezier]: https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Higher-order_B%C3%A9zier_curves
pub type Cubic = [Point; 4];
/// A cubic spline.
pub type CubicSpline = Vec<Cubic>;

圆锥

/// A conic is defined by two end points `start` and `end` and a control point `control`. It is
/// also defined by a weight `weight` (_w_) which is a non-negative number. The weight has a
/// default value of 1. A conic is also known as an ellipse, circle, parabola, or hyperbola
/// depending on the value of the weight and the relative positions of the control, start, and end
/// points.
///
/// <https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/NURBS/RB-conics.html>
#[derive(Clone, Default)]
pub struct Conic {
    pub start: Point,
    pub end: Point,
    pub control: Point,
    /// The weight of the conic. If _w_==1, parabolic. If _w_ < 1, elliptical. If _w_ > 1,
    /// hyperbolic.
    pub weight: f32
}

二次

/// A quadratic [`Bezier` segment][quad-bezier].
///
/// [quad-bezier]: https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Quadratic_curves
pub type Quad = [Point; 3];
/// A [quadratic spline][quad-spline].
///
/// [quad-spline]: https://en.wikipedia.org/wiki/B-spline#Quadratic_splines
pub type QuadSpline = Vec<Quad>;

转换

cu2qu

/// Convert a cubic Bézier curve to a quadratic spline segment.
pub trait CurveToQuadratic {
    fn curve_to_quadratic(&self, max_err: f32) -> Result<QuadSpline, ApproxNotFoundError>;
}

/// Convert a vector of cubic Bézier curves to a vector of quadratic spline segments.
pub trait CurvesToQuadratic {
    fn curves_to_quadratic(&self, max_errors: Vec<f32>) -> Result<Vec<QuadSpline>, ApproxNotFoundError>;
}

impl CurveToQuadratic for Cubic {}
impl CurvesToQuadratic for Vec<Cubic> {}

co2qu

/// Convert a “conic” (rational quadratic) Bézier curve to N quadratic spline segments.
impl Conic {
    pub fn as_quads(&self, tol: f32) -> QuadSpline {
        let mut pow2 = self.quad_pow2(tol);
        let orig_pow2 = pow2;
        let ret = self.chop_into_quads_pow2(&mut pow2);
        log::debug!("Tolerance {} yielded QuadSpline of len {}", tol, pow2);
        if orig_pow2 != pow2 {
            log::warn!("Tolerance {} caused lines to be generated, not quads", tol);
        }
        ret
    }
}

qu2cu

/// Trait for exact cubic Bézier curve generation from quadratic.
pub trait QuadToCubic<QCO: Default, const N: usize> {
    fn quad_to_cubic(self) -> [QCO; N];
}

cucoqu(ク・コ・キュ) — 三次 ← 圆锥 ← 二次 (三⇒曲⇐円⇒線⇐二)

用英语阅读

© 2022 フレッド・R・ブレンナン、MFEK著者達、Skia著者達、そしてGPT3型なに?

cucoqu(发音:ク・コ・キュ)是一个Rust(ラスト)库,用于在不同类型的贝塞尔自由曲线之间进行转换。目前,它只支持在类型设计和绘制曲线中最常用的类型:三次贝塞尔曲线、二次贝塞尔曲线,以及一种圆锥线(二次有理贝塞尔曲线)。

此库取代了MFEK中许多对Skia的C++代码的调用,并替换了其点类型之间的转换。

待办事项列表

  • 任意提高n次贝塞尔段的多项式次数

API

类型列表

Cubic (cu)

self[0]self[3]为贯穿三次贝塞尔曲线(段)。self[1..=2]是控制点。也就是说,Cubic的类型包含4个点构成的凸包。因此,CubicSpline的类型是三次贝塞尔曲线的数组。

pub type Cubic = [Point; 4];
pub type CubicSpline = Vec<Cubic>;

Conic (co)

由起点start、终点end、控制点(以及顶点)control和权重weightw)定义的圆锥曲线。权重是非负数,默认为1。圆锥曲线根据权重、控制点、起点和终点的相对位置被称为椭圆、圆、抛物线或双曲线。

👉︎关于w

w是圆锥曲线的权重。

w=1时,圆锥曲线是抛物线部分。
w小于1时,是椭圆曲线部分。
w大于1时,是双曲线部分。

#[derive(Clone, Default)]
pub struct Conic {
    pub start: Point,
    pub end: Point,
    pub control: Point,
    pub weight: f32
}

Quad (qu)

self[0] から self[2] までを涵盖的三次贝塞尔曲线(段)。 self[1] 是顶点。也就是说,因为Quad的型包含3个点的凸包,所以凸包必定是三角形。因此,QuadSpline的型是二次贝塞尔曲线的数组。

pub type Quad = [Point; 3];
pub type QuadSpline = Vec<Quad>;

转换

cu2qu

将三次贝塞尔曲线转换为二次曲线。

pub trait CurveToQuadratic {
    fn curve_to_quadratic(&self, max_err: f32) -> Result<QuadSpline, ApproxNotFoundError>;
}

pub trait CurvesToQuadratic {
    fn curves_to_quadratic(&self, max_errors: Vec<f32>) -> Result<Vec<QuadSpline>, ApproxNotFoundError>;
}

impl CurveToQuadratic for Cubic {}
impl CurvesToQuadratic for Vec<Cubic> {}

co2qu

二次有理贝塞尔曲线转换为二次贝塞尔曲线。

impl Conic {
    pub fn as_quads(&self, tol: f32) -> QuadSpline {
        let mut pow2 = self.quad_pow2(tol);
        let orig_pow2 = pow2;
        let ret = self.chop_into_quads_pow2(&mut pow2);
        log::debug!("Tolerance {} yielded QuadSpline of len {}", tol, pow2);
        if orig_pow2 != pow2 {
            log::warn!("Tolerance {} caused lines to be generated, not quads", tol);
        }
        ret
    }
}

qu2cu

将二次贝塞尔曲线转换为三次曲线。

pub trait QuadToCubic<QCO: Default, const N: usize> {
    fn quad_to_cubic(self) -> [QCO; N];
}

依赖关系

~9MB
~177K SLoC