1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use CubicBezierSegment;
use QuadraticBezierSegment;
use Line;
pub fn cubic_to_quadratic<F>(cubic: &CubicBezierSegment, _tolerance: f32, cb: &mut F)
where
F: FnMut(QuadraticBezierSegment),
{
mid_point_approximation(cubic, cb);
}
pub fn mid_point_approximation<F>(cubic: &CubicBezierSegment, cb: &mut F)
where
F: FnMut(QuadraticBezierSegment),
{
let (c1, c2) = cubic.split(0.5);
let (c11, c12) = c1.split(0.5);
let (c21, c22) = c2.split(0.5);
cb(single_curve_approximation(&c11));
cb(single_curve_approximation(&c12));
cb(single_curve_approximation(&c21));
cb(single_curve_approximation(&c22));
}
pub fn single_curve_approximation(cubic: &CubicBezierSegment) -> QuadraticBezierSegment {
let l1 = Line { point: cubic.from, vector: cubic.ctrl1 - cubic.from };
let l2 = Line { point: cubic.to, vector: cubic.ctrl2 - cubic.to };
let cp = match l1.intersection(&l2) {
Some(p) => p,
None => cubic.from.lerp(cubic.to, 0.5),
};
QuadraticBezierSegment {
from: cubic.from,
ctrl: cp,
to: cubic.to,
}
}