3.3.1. Exponentielle accelerandi und ritardandi
Abbildung 3.1. Videobeispiel für ein exponentielles accelerando
Abbildung 3.2. Beispiel für ein exponentielles accelerando
Beschleunigungen, wie sie in Abbildung 3.2, „Beispiel für ein exponentielles accelerando“ beim wiederholten Aufschlagen eines selbsttätig springenden Balls auf dem Boden erzeugt werden, sind exponentiell. Exponentiell bedeutet, dass das Zeit’verhältnis' zweier benachbarter Aufschläge des Balls 'konstant' ist. Im folgenden Beispiel sind die Zeitdifferenzen (Einsatzabstände bzw. Rhythmen) aus der Abbildung und darunter deren Verhältnisse dargestellt:
;; Einsatzabstände eines springenden Balls: 1.000 0.774 0.599 0.464 0.359 0.278 0.215 0.167 0.129 0.1 ;; Zeitverhältnisse benachbarter Einsatzabstände: 0.774/1.000 = 0.77 0.599/0.774 = 0.77 0.464/0.599 = 0.77 0.359/0.464 = 0.77 0.278/0.359 = 0.77 0.215/0.278 = 0.77 0.167/0.215 = 0.77 0.129/0.167 = 0.77 0.100/0.129 = 0.77
Um es allgemein zu formulieren, kann man die folgende Funktion exp-interpol
definieren, die eine exponentielle Interpolation von min
nach max
für einen x Wertebereich von [0..1]
errechnet. Bei x=0
ist das Ergebnis min
und bei x=1
ist das Ergebnis max
. Dazwischenliegende Werte für x ergeben Zwischenwerte, die exponentiell verteilt sind. Exponentiell bedeutet in diesem Fall, dass für jede beliebige gleichmäßige Teilung der x-Werte von 0 bis 1 gilt, dass das Verhältnis zwischen benachbarten Werten konstant ist.
(defun exp-interpol (x min max) (* min (expt (/ max min) x))) ;; Beispiel: ;; ;; min = 0.1, max = 1 ;; ;; x = 0: (exp-interpol 0 0.1 1) ;; -> 0.1 ;; x = 1: (exp-interpol 1 0.1 1) ;; -> 1.0 ;; x = 0.5: (exp-interpol 0.5 0.1 1) ;; -> 0.31622776 ;;; Teilung in 5 exponentiell gleichmäßig verteilte Werte: (loop for x from 0 to 4 collect (exp-interpol (/ x 4) 0.1 1)) ;;; -> (0.1 0.17782794 0.31622776 0.56234133 1.0) ;;; Teilung in 7 exponentiell gleichmäßig verteilte Werte: (loop for x from 0 to 6 collect (exp-interpol (/ x 6) 0.1 1)) ;;; -> (0.1 0.14677994 0.21544348 0.31622776 0.46415886 0.68129206 ;;; 1.0)
Das Beispiel mit dem springenden Ball vom Anfang des Kapitels lässt sich also mit Hilfe der Funktion exp-interpol
folgendermaßen errechnen:
(defparameter *testreihe* (loop for x from 0 to 9 collect (exp-interpol (/ x 9) 1 0.1))) ;;; -> (1.0 0.7742637 0.59948426 0.4641589 0.35938138 0.27825594 ;;; 0.21544348 0.16681005 0.12915497 0.1) (loop for (x y) on *testreihe* while y collect (/ y x)) ;;; -> (0.7742637 0.7742637 0.7742637 0.7742637 0.7742637 0.77426374 ;;; 0.7742636 0.7742637 0.7742637)
Daraus lässt sich ein common music Prozess formulieren, der ein acc von einem gegebenen Anfangswert zu einem gegebenen Endwert in einer gegebenen Anzahl von Schritten durchführt.
(defun acc (anzahl anfang ende) (process for rhythm in (loop for x from 0 to anzahl collect (exp-interpol (/ x anzahl) anfang ende)) output (new midi :duration (- rhythm 0.01)) wait rhythm)) (sprout (acc 40 0.5 0.04))