Physiksimulationen haben eine unglaubliche Eigenschaft: Sie können gestoppt, zurückgespult und wiedergegeben werden. Dies ist ein sehr mächtiges Werkzeug, mit dem ungewöhnliche Welten erzeugt werden können. In diesem Beitrag werde ich beschreiben, wie ich damit den Klang der Bälle synchronisiert habe, die auf berühmte Musik treffen. Ich frage die Interessierten unter dem Schnitt!
Einführung
Ich liebe es, alle Arten von ausgefallenen Visualisierungen, Physiksimulationen und all diese Dinge zu erstellen. Und so hatte ich vor zwei oder drei Jahren, als ich meine nächste Idee entwickelte , eine Idee, aber was ist, wenn wir die physische Welt so erzeugen, dass die darin ablaufenden Prozesse eine Melodie erzeugen? In einer Computersimulation können wir jederzeit einen Rollback durchführen, die Optionen durchgehen, die beste auswählen und gleichzeitig alle Informationen über die Melodie haben: Noten, Spielzeit einer Note. Ich hatte also die Idee, bis zu besseren Zeiten in meinem Kopf zu leben, bis ich Zeit hatte, etwas in Quarantäne zu schreiben, und so erschien dieses Projekt mit diesem Artikel.
Modell
Zunächst entschied ich mich für ein ziemlich einfaches Modell. In meinem Modell gibt es nur zwei Arten von Objekten: Murmeln und Plattformen oder Bretter. Plattformen haben streng feste Koordinaten, werden durch zwei Endpunkte festgelegt und haben eine konstante Breite. Die Kugeln fallen unter den Einfluss der Schwerkraft und können nach den Gesetzen der Physik von den Plattformen abprallen. Außerdem habe ich mich entschieden, nur absolut elastische Kollisionen zu verwenden, damit die Energie des Systems immer unverändert bleibt. Das Wichtigste ist jedoch, dass beim Zusammenprall von Ball und Plattform ein Sound gespielt wird, jede Plattform ihren eigenen Sound hat und aus mehreren Noten gleichzeitig bestehen kann.
Daher besteht unsere Welt aus vielen Plattformen, denen jeweils ein Sound zugewiesen ist. Und die Kugeln, die in diese Welt fallen, können eine Folge von Klängen erzeugen, und in unserem Fall sogar eine Melodie.
Algorithmus
Wir haben das Modell herausgefunden, aber wie kann man eine solche Welt erzeugen, damit die Klänge schlagender Bälle in einer bekannten Melodie aufeinander treffen ?
Ich entschied mich dennoch für die ungeschickteste, die sich als ziemlich gute, rekursive Brute Force und im einfachen Volk als Bruteforce erwies . Aber damit alles so funktioniert, wie es sollte, musste ich ein paar Tricks anwenden. Alle nachfolgenden Schritte werden innerhalb einer rekursiven Funktion ausgeführt:
- Wir simulieren die Welt bis zum nächsten Moment, in dem Sie eine Note spielen müssen.
- Wenn während der Simulation eine unerwünschte Kollision aufgetreten ist, kehren wir zur höheren Ebene zurück.
- , , , . , .
. «» ( , , ).+ 70 ∘ - 4. .
- 5. ,
- 6. , ,
, , .m
Auf dem Bild sehen Sie die Visualisierung eines Schritts dieses Algorithmus:
Hinweis
, , , . , , . , . , .
Rekursion steckt fest
Wie jeder Bruteforce- Algorithmus hat auch dieser einen Nachteil in Form von "Rekursion steckt fest". Dies geschieht, wenn eine "schlechte" Plattform die zukünftige Generierung der Karte nicht zulässt, Sie jedoch gleichzeitig einen ausreichend großen Teil davon generieren können, jedoch nicht vollständig ... In diesem Fall bleibt die Rekursion hängen, bis alle Optionen im Rekursions-Teilbaum aufgelistet sind, die diese "schlechte" Plattform erzeugt. Es ist kein Problem, wenn die Höhe dieses Teilbaums 4 bis 8 Rekursionsstufen nicht überschreitet, aber manchmal 20 bis 30 Stufen erreichen kann, was es einfach unmöglich macht, alle Varianten dieses Teilbaums zu durchlaufen.
Daher habe ich mich bei meiner Implementierung für eine Heuristik entschieden, um das Problem zu lösen. Die Idee ist, einen Teil der Rekursion zu reduzieren, wenn solche Fälle erkannt werden. Es schien mir das offensichtlichste, zu dem ich zurückkehren konnte
können Sie das Ergebnis dieser Heuristik in der Demo sehen, wenn der Fortschritt der Karte Generation wird manchmal um 10% zurückgesetzt werden. Gleichzeitig können Sie die Generierung der Karte in angemessener Zeit abschließen.
Iterative Generierung
Lassen Sie uns nun das folgende Problem lösen: Nach dem Start der Kartengenerierung friert die Seite 10 bis 30 Sekunden lang ein und es ist unmöglich zu verstehen, was überhaupt passiert, alles ist gefallen oder es dauert nur sehr lange, bis die Karte erstellt wird. Aus diesem Grund habe ich beschlossen, auch eine iterative Implementierung des Generierungsalgorithmus zu schreiben, damit Sie eine Karte in kleinen Teilen konsistent erstellen können.
Ich musste nichts Neues erfinden, sondern habe den rekursiven Algorithmus einfach auf einen expliziten Stapel geschrieben. Daher wurde auf der Seite ein Fortschrittsbalken angezeigt, der Ihnen hilft zu verstehen, dass der Code nicht gefallen ist. Es dauert nur lange, bis ein geeigneter Ort für Plattformen für Ihren Track gefunden ist.
In einigen Fällen kann die Generierung zu lange dauern. Dazu habe ich die Wiedergabetaste hinzugefügt , die die Generierung stoppt und die Simulation der Welt startet.
Klingelton herunterladen
Um eine Melodie herunterzuladen, verwende ich MIDI- Dateien, aber zuvor habe ich sie über tonjs.github.io/Midi ausgeführt , um sie in einen browserfreundlichen JSON umzuwandeln (im Moment bietet die Demo jedoch nicht die Funktionalität zum Herunterladen meiner Datei, sondern nur eine Auswahl aus einer vorbereiteten Liste).
Es ist auch wichtig zu beachten, dass die Midi-Datei häufig mehrere parallele Spuren enthält. Da mein Algorithmus bisher jedoch nur mit einer Kugel funktioniert, wird nur eine Spur mit der größten Anzahl von Noten geladen.
Ergebnisse
Nachdem ich einige Effekte hinzugefügt hatte, nahm ich das erste Video auf:
Nach der Überprüfung es mehrere
Das Video zeigt möglicherweise eine Desynchronisation, das habe ich später bemerkt. Wenn Sie mit der Demo auf die Seite gehen , sollte es keine Nicht-Synchronisation geben (der Sound wird tatsächlich nur abgespielt, wenn der Beat registriert ist).
Was weiter?
Ich habe vor, die Möglichkeit hinzuzufügen, solche Karten für mehrere Bälle gleichzeitig zu generieren. Ich habe Ideen dazu, ich habe verschiedene Optionen getestet, aber bisher arbeiten alle extrem langsam, um einen vollständigen Track zu generieren.
Eine andere Idee von mir war es, neue Objekte hinzuzufügen: Knöpfe, Sprungbretter, Waffen (?), Ringe ... die Liste kann ergänzt werden :) Sie können die Welt erheblich diversifizieren.
Der Code
Sie finden den gesamten Quellcode in meinem Repository.
Vorschläge, Pull-Anfragen und Quiz sind willkommen!