mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
internal/stroke: optimize SplitCubic
│ sec/op │ sec/op vs base │ SplitCubic/4-10 37.36n ± 0% 36.16n ± 0% -3.21% (p=0.000 n=10) SplitCubic/8-10 74.53n ± 0% 72.21n ± 0% -3.12% (p=0.000 n=10) SplitCubic/16-10 149.3n ± 1% 144.5n ± 0% -3.22% (p=0.000 n=10) SplitCubic/33-10 340.1n ± 0% 334.4n ± 0% -1.65% (p=0.000 n=10) Signed-off-by: Egon Elbre <egonelbre@gmail.com>
This commit is contained in:
@@ -709,7 +709,11 @@ func approxCubeTo(quads *[]QuadSegment, splits int, maxDistSq float32, from, ctr
|
||||
// and use the midpoint between the two curves Q1 and Q2 as control point:
|
||||
//
|
||||
// C = (3ctrl0 - pen + 3ctrl1 - to)/4
|
||||
c := ctrl0.Mul(3).Sub(from).Add(ctrl1.Mul(3)).Sub(to).Mul(1.0 / 4.0)
|
||||
// using, q0 := 3ctrl0 - pen, q1 := 3ctrl1 - to
|
||||
// C = (q0 + q1)/4
|
||||
q0 := ctrl0.Mul(3).Sub(from)
|
||||
q1 := ctrl1.Mul(3).Sub(to)
|
||||
c := q0.Add(q1).Mul(1.0 / 4.0)
|
||||
const maxSplits = 32
|
||||
if splits >= maxSplits {
|
||||
*quads = append(*quads, QuadSegment{From: from, Ctrl: c, To: to})
|
||||
@@ -718,10 +722,12 @@ func approxCubeTo(quads *[]QuadSegment, splits int, maxDistSq float32, from, ctr
|
||||
// The maximum distance between the cubic P and its approximation Q given t
|
||||
// can be shown to be
|
||||
//
|
||||
// d = sqrt(3)/36*|to - 3ctrl1 + 3ctrl0 - pen|
|
||||
// d = sqrt(3)/36 * |to - 3ctrl1 + 3ctrl0 - pen|
|
||||
// reusing, q0 := 3ctrl0 - pen, q1 := 3ctrl1 - to
|
||||
// d = sqrt(3)/36 * |-q1 + q0|
|
||||
//
|
||||
// To save a square root, compare d² with the squared tolerance.
|
||||
v := to.Sub(ctrl1.Mul(3)).Add(ctrl0.Mul(3)).Sub(from)
|
||||
v := q0.Sub(q1)
|
||||
d2 := (v.X*v.X + v.Y*v.Y) * 3 / (36 * 36)
|
||||
if d2 <= maxDistSq {
|
||||
*quads = append(*quads, QuadSegment{From: from, Ctrl: c, To: to})
|
||||
|
||||
Reference in New Issue
Block a user