Am Fr., 27. Mai 2022 um 14:59 Uhr schrieb Jean Abou Samra <j...@abou-samra.fr>: > > > > Le 27/05/2022 à 13:28, Thomas Morley a écrit : > > I decided to go for a better approximation of the bow-length, but > > dropped some comments what to do, if execution time gets worse. > > https://lsr.di.unimi.it/LSR/Item?u=1&id=1028 > > Here's an experiment: > > \version "2.23.9" > > #(define (bezier-curve control-points t) > "Given a Bezier curve of arbitrary degree specified by @var{control-points}, > compute the point at the specified position @var{t}." > (if (< 1 (length control-points)) > (let ((q0 (bezier-curve (drop-right control-points 1) t)) > (q1 (bezier-curve (drop control-points 1) t))) > (cons > (+ (* (car q0) (- 1 t)) (* (car q1) t)) > (+ (* (cdr q0) (- 1 t)) (* (cdr q1) t)))) > (car control-points))) > > #(define (bezier-approx-length control-points from to steps) > "Given a Bezier curve of arbitrary degree specified by @var{control-points}, > compute its approximate arc length between the positions @var{from} and > @var{to}." > (let* ((params (iota steps from (/ (- to from) (1- steps)))) > (points (map (lambda (x) (bezier-curve control-points x)) params)) > (length > (fold > (lambda (a b prev) > (+ prev (ly:length (- (car a) (car b)) (- (cdr a) (cdr > b))))) > 0 > (drop points 1) > (drop-right points 1)))) > ; Need to support negative length when the range is inverted. > (if (< from to) length (- length)))) > > > #(let ((bezier '((0 . 0) (1 . 1) (2 . 1) (3 . 0)))) > (for-each > (lambda (n) > (ly:message "bezier-approx-length with ~a segments: ~a" > n > (bezier-approx-length bezier 0 1 n))) > '(10 50 100 500 1000 5000 10000))) > > > => > > > bezier-approx-length with 10 segments: 3.439011160316537 > > bezier-approx-length with 50 segments: 3.44323346616539 > > bezier-approx-length with 100 segments: 3.4433446505712593 > > bezier-approx-length with 500 segments: 3.4433793042010272 > > bezier-approx-length with 1000 segments: 3.443380369827364 > > bezier-approx-length with 5000 segments: 3.4433807099411706 > > bezier-approx-length with 10000 segments: 3.443380720552721 > > I don't think doing many iterations is worth it here. >
Using your test-code I did own experiments with more crazy control-points like '((17 . 0) (8 . 10) (22 . 10) (13 . 0)). While I got differences up to ~0.15, those beziers will not occur in real music, afact. Thus I'll reduce the steps in said snippt to 10, usually very nice already. Thanks, Harm