Einführung
Der Boids-Algorithmus ist eine relativ einfache Demonstration des aufkommenden Verhaltens in einer Gruppe. Es hat drei Hauptregeln, wie von seinem Schöpfer Craig Reynolds beschrieben:
Das grundlegende Flockmodell besteht aus drei einfachen Lenkverhalten, die beschreiben, wie ein einzelner Boid anhand der Positionen und Geschwindigkeiten seiner in der Nähe befindlichen Flockkameraden manövriert:
- Trennung : Lenken, um ein Überfüllen der örtlichen Herdenkameraden zu vermeiden.
- Ausrichtung : Steuere in Richtung des durchschnittlichen Kurses der lokalen Herdenkameraden.
- Kohäsion : Steuern Sie, um sich der durchschnittlichen Position lokaler Herdenkameraden zu nähern.
Jedes Boid hat direkten Zugriff auf die geometrische Beschreibung der gesamten Szene. Zum Beflocken muss es jedoch nur auf Flockkameraden in einer bestimmten kleinen Nachbarschaft um sich herum reagieren. Die Nachbarschaft ist durch einen Abstand (gemessen von der Mitte des Boids) und einen Winkel , gemessen von der Flugrichtung des Boids, gekennzeichnet. Flockmates außerhalb dieses Stadtviertels werden ignoriert. Die Nachbarschaft könnte als Modell für eine eingeschränkte Wahrnehmung angesehen werden (wie bei Fischen in trübem Wasser), aber es ist wahrscheinlich richtiger, sie als die Region zu betrachten, in der Herdenkameraden die Steuerung eines Boids beeinflussen.
Ich bin nicht perfekt, wenn ich Dinge erkläre, daher empfehle ich dringend, die Quelle zu überprüfen . Er hat auch einige super informative Bilder auf seiner Seite.
Herausforderung
Ausgehend von der Anzahl der Boids (simulierten Entities) und der Anzahl der Frames wird eine Animation der Simulation ausgegeben.
- Die Boids sollten als roter Kreis gerendert werden, wobei eine Linie innerhalb des Kreises die Überschrift anzeigt, in die der Boid zeigt:
- Der Winkel jedes Boids (wie von Reynolds beschrieben) sollte volle 300 Grad betragen. (nicht 360)
- Die Startüberschrift und die Position jedes Boids sollten gleichmäßig zufällig sein (aber gesät sein, so dass die Ausgabe immer noch bestimmt ist) sowie die Position.
- Wenn der Radius des Boids 1 ist, sollte der Radius der Nachbarschaft 3 sein.
- Die Anzahl der Boids liegt zwischen 2 und 20.
- Die Anzahl der Frames liegt zwischen 1-5000
- Die Animation sollte mit mindestens 10 Millisekunden pro Bild und maximal 1 Sekunde mal der Anzahl der Boids abgespielt werden. (2 Boids = max. 2 Sekunden pro Frame, 3 Boids = max. 3 Sekunden pro Frame usw.)
- Die Ausgabeanimation sollte mindestens 5 Boid-Radien mal 5 Boid-Radien mal die Hälfte der Boid-Anzahl betragen. Die minimale Größe für 2 Boids wäre also 10 Boid-Radien mal 10 Boid-Radien, das Minimum für 3 Boids wären 15 Boid-Radien mal 15 Boid-Radien usw.
- Der Radius jedes Boids muss mindestens 5 Pixel und höchstens 50 Pixel betragen.
- Die Geschwindigkeit jedes Boids muss begrenzt werden, damit er sich nicht mehr als 1/5 seines Radius in einem Frame bewegt.
- Die Ausgabe muss bestimmt werden, damit dieselbe Eingabe dieselbe Ausgabe erzeugt, wenn sie mehrmals ausgeführt wird.
- Wenn ein Boid eine Grenze erreicht, sollte es auf die andere Seite gewickelt werden. Ebenso sollte die Nachbarschaft um jedes Boid auch die Grenzen umschließen.
Regeln für den Algorithmus
In diesem Fall hat jedes Boid einen Sektor um sich herum, der sich über 300 Grad erstreckt und auf der Überschrift des Boids zentriert ist. Alle anderen Boids in dieser "Nachbarschaft" werden als "Nachbarn" oder (um Reynolds 'Begriff zu verwenden) "Herdenkameraden" angesehen.
Jedes Boid sollte seinen Steuerkurs anpassen, um Kollisionen zu vermeiden und einen komfortablen Abstand von einem Boid-Radius zu seinen Nachbarn einzuhalten. (Dies ist der "Separations" -Aspekt des Algorithmus. Der eine Boid-Radius kann umgangen werden, sollte aber wie ein Gummiband aussehen und wieder einrasten.)
Jedes Boid sollte zusätzlich seine Richtung so anpassen, dass es näher an der durchschnittlichen Richtung der anderen Boids in seiner Nachbarschaft liegt, sofern dies nicht die erste Regel stört. (Dies ist der "Ausrichtungs" -Aspekt des Algorithmus.)
Jedes Boid sollte sich in Richtung der durchschnittlichen Position seiner Herdenmitglieder drehen, solange dies keine Kollision verursacht oder die zweite Regel erheblich beeinträchtigt.
In seiner Arbeit zu diesem Thema erklärt er dies wie folgt:
Um eine simulierte Herde zu bauen, beginnen wir mit einem Boid-Modell, das den geometrischen Flug unterstützt. Wir fügen Verhaltensweisen hinzu, die den entgegengesetzten Kräften der Kollisionsvermeidung und dem Drang, sich der Herde anzuschließen, entsprechen. Kurz als Regeln und in abnehmender Reihenfolge angegeben, sind die Verhaltensweisen, die zu einer simulierten Beflockung führen:
- Kollisionsvermeidung: Vermeiden Sie Kollisionen mit in der Nähe befindlichen Herdenmitgliedern
- Velocity Matching: Versucht, die Velocity mit in der Nähe befindlichen Flockmates abzugleichen
- Flockenzentrierung: Versuchen Sie, in der Nähe von Flockenkameraden zu bleiben
Detailliertere Beschreibung der Bewegung:
- Die Standardimplementierung des Boids-Algorithmus führt normalerweise eine Berechnung für jede der Regeln durch und führt diese zusammen.
- Für die erste Regel durchläuft der Boid die Liste der benachbarten Boids in seiner Nachbarschaft. Wenn der Abstand zwischen sich und dem Nachbarn geringer als ein bestimmter Wert ist, wird ein Vektor, der den Boid von seinem Nachbarn wegdrückt, auf die Boid-Überschrift angewendet.
- Für die zweite Regel berechnet das Boid die durchschnittliche Überschrift seiner Nachbarn und addiert einen kleinen Teil (wir verwenden 1/10 in dieser Herausforderung) der Differenz zwischen der aktuellen Überschrift und der durchschnittlichen Überschrift zu der aktuellen Überschrift.
- Für die dritte und letzte Regel mittelt das Boid die Positionen seiner Nachbarn und berechnet einen Vektor, der auf diese Position zeigt. Dieser Vektor wird mit einer noch kleineren Zahl multipliziert als für Regel 2 verwendet (für diese Herausforderung wird 1/50 verwendet) und auf die Überschrift angewendet.
- Das Boid wird dann in Richtung seiner Überschrift bewegt
Hier ist eine hilfreiche Pseudocode-Implementierung des Boids-Algorithmus.
Beispiel für Ein- und Ausgabe
Eingang:Ausgabe:5, 190 (5 Boids, 190 Frames)
Gewinnkriterium
Das ist Code-Golf , also gewinnt die kleinste Lösung in Bytes.
quelle
Antworten:
Verarbeitung 3.3.6 (Java) ,
932931940928957917904 Bytes-1 Byte von Jonathan Frech
+11 Byte, um besser mit der Spezifikation übereinzustimmen
-2 Byte von Kevin Cruijssen
-12 Byte für das Ändern von args in t ()
+29 Byte, weil ich Geisterbilder falsch
gemacht habe Schleifen anstelle von separaten Aufrufen für jeden Ghost
-13 Bytes zur Verwendung der Standard-FrameRate, 30
Nun, es ist ein Anfang für jemanden, der kein Java-Golf spielt. :)
Ich kenne keinen vernünftigen Weg, um Eingaben in der Verarbeitung vorzunehmen, daher sind die ersten beiden Variablen die Eingaben (und ich habe ihre Werte (5 Bytes) nicht in die Byteanzahl eingerechnet). Wenn dies ein Problem ist, kann ich andere Dinge ausprobieren.
Ich kenne auch keine gute Möglichkeit, es online zu versuchen (das Processing.js-Projekt kann diesen Codestil nicht verarbeiten), ohne die Dinge selbst zu hosten. und das ist etwas, was ich nicht unbedingt versuchen möchte. Lassen Sie mich wissen, ob ich etwas Kluges tun kann.
Formatierter Code mit Kommentaren
Beispielausgabe
n = 15, Frames = 400:
Oder dieselbe Animation, jedoch mit der Nachbarschaft der einzelnen Boids.
quelle
2*PI
nichtTAU
gespeichert werden?,i,
Zu,i=0,
und dann dasi=0
Innere der for-Schleife entfernen . (-1 Byte);frameCount%f==0
bisframeCount%f<1
(1 Byte);&&
bis&
im letzten if2*d>=p.dist(m)&q.angleBetween(v,q.sub(m,p))<=5*PI/6
(-1 Byte). Auch hier bin ich mir nicht sicher, ob dies möglich ist, aber da die Verarbeitung Java ziemlich ähnlich zu sein scheint, denke ich, dass dies der Fall ist. Sie können auch versuchen, ein GIF mit screentogif.com zu erstellen .JavaScript (ES6) + HTML5, 1200 Byte
Hier ist meine aktuelle Lösung mit der Canvas-API. Das
eval()
Ergebnis ist eine Curry-Funktion, deren erste Eingabe dieBoid
Grundgesamtheit und die zweite die Anzahl der Animationsframes ist. Sie könnenInfinity
für die kontinuierliche Animation verwenden.Das
eval(...)
ist 1187 Byte und<canvas id=c>
13 Byte, was insgesamt 1200 Byte ergibt. Das CSS ist nicht erforderlich, aber der Einfachheit halber können Sie die Ränder der Zeichenfläche sehen.Bearbeiten
Auf Wunsch ein weiteres Snippet mit einer Eingabe für die Boid-Population:
quelle
t.a+v+l/10+f/50
Wenn Sie den Wert in ändern,t.a+v/3+l/10+f/50
wird ein etwas interessanteres Verhalten erzeugt, aber das aktuelle Programm ist kleiner und entspricht immer noch den Spezifikationen.