1个不稳定版本
0.1.0 | 2022年12月19日 |
---|
#902 in 算法
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
和权重weight(w)定义的圆锥曲线。权重是非负数,默认为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