Zykloidulus bekommt Fourier-Transformation

Ich hatte mir mal ein T-Shirt bei getdigital.com gekauft. Da steht „All you need is L-O-V-E“, wobei jeder Buchstabe durch eine mathematische Formel in einem eigenen Koordinatensystem dargestellt wird. Fand ich ganz witzig. Seit dem dachte ich aber auch darüber nach, ob es auch möglich ist, den Schriftzug „love“ auch mit nur einer Formel darzustellen. Irgendwann hatte ich einmal was von Fourier-Transformation gehört und dass man damit Musiksignale in die einzelnen Sinuswellen, aber auch 2D-Formen in einzelne Drehbewegungen zerlegen kann.

In den letzten Tagen hatte ich an meinem Hobby-Projekt „Zykloidulus“ weiter programmiert, um mittels Fourier-Transformation Figuren in ihre Frequenzen zu zerlegen und mit den Daten zu experimentieren. Und es funktioniert ab heute prima:

 

Mein Programm habe ich rudimentär mit ein paar Bedienungselementen und der Möglichkeit, ein Polygon zu zeichnen ausgestattet. Mit dem fourier-Knopf lassen sich so aus einem Polygon die darin steckenden Frequenzen zu ermitteln und animiert darstellen. Die sich drehenden, aneinandergereihten Vektoren werden als rote Linien dargestellt, welche die vorgegebene Form näherungsweise schwarz nachzeichnen. Mit dem subdiv-Knopf lassen sich auf jeder Linie mittig ein zusätzlicher Punkt einfügen, um die Näherung noch genauer zu machen.

Am Ende des Videos wurde die Beispiel-Zeichnung in Parameter für 71 Drehbewegungen zerlegt:

 

spec = [
{ freq: -35, amp: 0.0003686, phase: -1.5236009 },
{ freq: -34, amp: 0.0012953, phase: -1.1669831 },
{ freq: -33, amp: 0.0023193, phase: -1.3474052 },
{ freq: -32, amp: 0.0082433, phase: -1.4717065 },
{ freq: -31, amp: 0.0295951, phase:  0.9387542 },
{ freq: -30, amp: 0.0118085, phase: -0.1819100 },
{ freq: -29, amp: 0.0084302, phase: -0.9733754 },
{ freq: -28, amp: 0.0107256, phase: -1.6145778 },
{ freq: -27, amp: 0.0055092, phase:  0.5508575 },
{ freq: -26, amp: 0.0282102, phase: -2.0025910 },
{ freq: -25, amp: 0.0140332, phase: -2.1524231 },
{ freq: -24, amp: 0.0096098, phase: -1.3614207 },
{ freq: -23, amp: 0.0052851, phase: -0.0287800 },
{ freq: -22, amp: 0.0102071, phase: -0.8459905 },
{ freq: -21, amp: 0.0229444, phase: -0.0303723 },
{ freq: -20, amp: 0.0336553, phase: -0.6223523 },
{ freq: -19, amp: 0.0193167, phase:  0.1048640 },
{ freq: -18, amp: 0.0222801, phase: -1.1807482 },
{ freq: -17, amp: 0.0201180, phase: -0.4136481 },
{ freq: -16, amp: 0.0151423, phase: -2.1911763 },
{ freq: -15, amp: 0.0389249, phase:  1.4865131 },
{ freq: -14, amp: 0.0276480, phase:  1.0410499 },
{ freq: -13, amp: 0.0580259, phase:  1.2996377 },
{ freq: -12, amp: 0.0588539, phase:  1.2406528 },
{ freq: -11, amp: 0.0620339, phase:  0.8851068 },
{ freq: -10, amp: 0.0204838, phase: -0.1967784 },
{ freq:  -9, amp: 0.0461501, phase:  1.0957855 },
{ freq:  -8, amp: 0.0940981, phase: -2.2153818 },
{ freq:  -7, amp: 0.2368071, phase: -2.2072689 },
{ freq:  -6, amp: 0.2375195, phase: -2.4316229 },
{ freq:  -5, amp: 0.5711301, phase:  2.0492726 },
{ freq:  -4, amp: 0.4427810, phase: -2.1482357 },
{ freq:  -3, amp: 0.5485490, phase: -2.3804487 },
{ freq:  -2, amp: 0.8690513, phase: -2.2145402 },
{ freq:  -1, amp: 1.6186980, phase: -1.9505409 },
{ freq:   0, amp: 2.1221538, phase:  1.6137504 },
{ freq:   1, amp: 0.1933930, phase: -1.5236009 },
{ freq:   2, amp: 0.1692300, phase: -1.1669831 },
{ freq:   3, amp: 0.1338133, phase: -1.3474052 },
{ freq:   4, amp: 0.2651344, phase: -1.4717065 },
{ freq:   5, amp: 0.6021577, phase:  0.9387542 },
{ freq:   6, amp: 0.1644724, phase: -0.1819100 },
{ freq:   7, amp: 0.0848002, phase: -0.9733754 },
{ freq:   8, amp: 0.0809638, phase: -1.6145778 },
{ freq:   9, amp: 0.0321103, phase:  0.5508575 },
{ freq:  10, amp: 0.1297364, phase: -2.0025910 },
{ freq:  11, amp: 0.0517852, phase: -2.1524231 },
{ freq:  12, amp: 0.0288296, phase: -1.3614207 },
{ freq:  13, amp: 0.0130220, phase: -0.0287800 },
{ freq:  14, amp: 0.0208185, phase: -0.8459905 },
{ freq:  15, amp: 0.0389687, phase: -0.0303723 },
{ freq:  16, amp: 0.0477998, phase: -0.6223523 },
{ freq:  17, amp: 0.0230053, phase:  0.1048640 },
{ freq:  18, amp: 0.0222801, phase: -1.1807482 },
{ freq:  19, amp: 0.0168923, phase: -0.4136481 },
{ freq:  20, amp: 0.0106615, phase: -2.1911763 },
{ freq:  21, amp: 0.0229186, phase:  1.4865131 },
{ freq:  22, amp: 0.0135555, phase:  1.0410499 },
{ freq:  23, amp: 0.0235503, phase:  1.2996377 },
{ freq:  24, amp: 0.0196179, phase:  1.2406528 },
{ freq:  25, amp: 0.0168105, phase:  0.8851068 },
{ freq:  26, amp: 0.0044540, phase: -0.1967784 },
{ freq:  27, amp: 0.0079181, phase:  1.0957855 },
{ freq:  28, amp: 0.0124655, phase: -2.2153818 },
{ freq:  29, amp: 0.0235417, phase: -2.2072689 },
{ freq:  30, amp: 0.0170531, phase: -2.4316229 },
{ freq:  31, amp: 0.0280702, phase:  2.0492726 },
{ freq:  32, amp: 0.0137665, phase: -2.1482357 },
{ freq:  33, amp: 0.0095076, phase: -2.3804487 },
{ freq:  34, amp: 0.0066519, phase: -2.2145402 },
{ freq:  35, amp: 0.0030856, phase: -1.9505409 }
]  

Jeder einzelne Eintrag im Array spec beschreibt einen sich um den Nullpunkt drehenden Vektor mit freq als Drehgeschwindigkeit, amp als Länge und phase als Startpunkt auf dem gedachten Kreis. Die Zeit t läuft von 0 bis 2 π, also genau einmal ‘rum. Beispielsweise beschreibt der erste Eintrag einen Vektor, der sich 35fach rechtsherum dreht, 0,0003686 Einheiten lang ist, und bei -1.5236009 Radiant, bei -87,3 Grad mit der Drehung startet.

 

Wie funktioniert die Fourier-Transformation?

Ich versuche es erst einmal mit eigenen Worten: Gegeben ist eine Menge von anzahl Punkte P[n]. Frequenz freq läuft in einer Schleife von –anzahl/2 bis +anzahl/2 mit Schrittweite 1 durch. Und jetzt kommt die Magie: Man verdreht die Punkte P[n] freq-mal um den Koordinatenursprung, ermittelt dann deren geometrischen Schwerpunkt S (Durchschnitt aller x- und aller y-Koordinaten), und daraus dann mit atan2() den Startwinkel phase und Phytagoras die Länge amp für diese Frequenz. 

Für wen das zu trocken klingt: Hier sind „meine“ Youtube-Lehrer:

Es ist ein ganz spannendes Thema, denn Fourier-Transformation und das Arbeiten mit Frequenzspektren ermöglicht zum Beispiel auch die Ausgabe als Audiodatei bei gleichzeitigen Herausfiltern von zu hohen oder störenden Frequenzen, was auf einem Oszilloskop die Ecken abrunden und damit das Knacksen minimieren würde. 

Oszilloskopmusik-Pionier Jerobeam Fenderson hat mit seiner Musik Polygone, Animationen und kleine Filme auf einem Oszilloskop erscheinen lassen, wenn es im sogenannten X-Y-Modus eingestellt ist. Dabei wobei die x-Koordinate einer Zeichnung als linker und die y-Koordinate als rechter Stereokanal ausgegeben. Ein sehr inspirierender Ansatz, der zum experimentieren einlädt. 

Mein Programm vermag auch die Näherungszeichnung aus den sich drehenden Vektoren als eine einsekündige Audiodatei auszugeben. Hier ist die Ansicht auf einem Oszilloskop (simuliert mit Oscilloscope! und mit dem Smartphone abgefilmt).

Wie sieht die Formel aus?

Wie am Anfang erwähnt, ging es mir zunächst darum, die mathematische Formel einer durch summierte Drehbewegungen ausgedrückten Zeichnung mit darzustellen. Allerdings ist die noch sehr lang und unübersichtlich. Für die Hand würde das so aussehen:

Auch wenn ich bereits die Komponente mit der Frequenz 0 weggelassen habe – die verschiebt ja nur die gesamte Zeichnung auf der Ebene umher – sind es noch zwei sehr lange Formeln. Das Ganze braucht also noch ein wenig Kosmetik, damit es verständlich wird und eines Tages mal auf ein T-Shirt passt. Der erste Schritt ist das Rechnen mit  komplexe Zahlen statt Vektoren aus X und Y.

Die Koordinate eines Punktes lässt sich statt als Vektor aus zwei Koordinaten (linkes Bild) auch als komplexe Zahl beschreiben (rechts). Vorteil: Die Summenformel kann Rechts-Links-Komponenten und Oben-Unten-Komponenten enthalten. Letztere werden mit i multipliziert. Merke: Multiplizieren mit i dreht um 90 Grad nach links um den Koordinatenursprung. z( t ) ist die Funktion, welche die Hand in ein Koordinatensystem, auf die komplexe Zahlenebene zeichnen würde:

Challenge für die Beispiel-Hand eigentlich erfüllt. Doch da geht noch was.

Der nächste Schritt ist das Ersetzen von a*(cos(x)+i*sin(x)) durch eine Funktion a*cis(x). Das kommen die Dopplungen raus, da man ja den Winkel in cos() und sin() schreiben muss. So kommen die Terme in der Klammer nur einmal vor. Das erspart etwa die Hälfte:

Das ist nun die Formel für eine Funktion, die eine Hand in ein Koordinatensystem zeichnet. Sieht doch schonmal ganz gut aus, oder?

Sven

Sven Wachsmuth wurde 1978 geboren, ist in Emleben bei Gotha aufgewachsen, wohnt seit 2003 in Erfurt. Er experimentiert seit Anfang der 1990er sowohl mit den kreativen Dingen, die man so mit einem Computer anstellen kann als auch mit traditionellen Techniken wie Schreiben, Zeichnen, Fotografie und Modellbau. Inspiration findet er in der Natur und der Geometrie. mehr erfahren

Schreibe einen Kommentar