Schwerkraft in Aktion

Die Untersuchung von Kräften ist von zentraler Bedeutung für die Dynamik, die Untersuchung von Bewegungsursachen und Bewegungsänderungen. Erdanziehungskraft ist ein Beispiel; Es ist das, was dazu führt, dass sich die Satelliten um Planeten drehen und wir am Boden bleiben.

In diesem Tutorial erstellen wir eine Simulation eines solchen Phänomens und können mit Partikeln auf der Szene beobachten, experimentieren und damit spielen.

Unter allen erzeugten Partikeln wird ein Hauptpartikel andere anziehen. Wenn sich diese Partikel in Richtung des Hauptpartikels bewegen, können Benutzer auf dieses Hauptpartikel klicken, um es mit sich zu ziehen, wodurch diese Partikel ihren Kurs umleiten. Diese Partikel bewegen sich nicht mehr, wenn sie mit der Kante der Hauptkugel kollidieren, aber sie überlappen sich nicht.

Die Struktur dieses Tutorials ist so aufgebaut, dass eine kurze Theorie in Physik vermittelt wird, bevor die Implementierung der Simulation vorgestellt wird. Genießen!


Endergebnisvorschau

Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:

Klicken und ziehen Sie den großen grünen Kreis, um ihn zu verschieben, und beobachten Sie, wie die kleinen blauen Kreise reagieren.


Schritt 1: Gravitationskraft, Formel

Zunächst ein Vorwort zur Physik. Die anziehende Gravitationskraft zwischen zwei beliebigen Objekten wird durch die folgende Formel ausgedrückt:

F: Anziehungskraft, die auf ein Objekt von Interesse ausgeübt wird (p2) durch
ein beliebiges Teilchen (p1).

G: Gravitationskonstante

m1: Masse von p1

m2: Masse von p2

r: Abstand zwischen p1 und P2

Beachten Sie Folgendes besonders:

  1. Die Beziehung zwischen Schwerkraft und Entfernung: F ist umgekehrt proportional zum Quadrat der Entfernung, die die beiden Teilchen voneinander trennt. Dies bedeutet, je näher A und B sind, desto höher ist die Anziehungskraft zwischen ihnen und umgekehrt. Wenn Sie den Abstand verdoppeln, sinkt die Kraft auf ein Viertel des ursprünglichen Werts.
  2. Der Wert der Gravitationskonstante G beträgt wissenschaftlich 6,67259 x 10-11 N * m2 / kg2. 500 ersetzt diesen Wert jedoch in der Flash-Umgebung.
  3. Wir können die Breite der Teilchen auf ihre Masse beziehen. Für dieses Beispiel habe ich die Masse eines Partikels als die Hälfte seines Radius definiert.

Schritt 2: Newton's 2nd Gesetz, Gleichung

Um die Kraft in die Kinematik zu übersetzen, müssen wir die Beschleunigung der Teilchen berechnen. Die berühmte Gleichung von Sir Isaac Newton ist unten dargestellt:

F: Schwerkraft, die auf ein Objekt von Interesse ausgeübt wird (p2)

m: Masse des Gegenstandes von Interesse (p2)

ein: Beschleunigung des interessierenden Objekts (p2) unter dem Einfluss von F

Daraus folgt, dass eine höhere Kraft, die auf das Partikel A ausgeübt wird, zu einer höheren Beschleunigung führt (vorausgesetzt, seine Masse bleibt gleich). Diese Beschleunigung ändert die Geschwindigkeit des Partikels.


Schritt 3: Projekt starten

Die Implementierung erfolgt in der FlashDevelop-IDE. Erstellen Sie Ihre Projektdatei.

  1. Starten Sie ein neues Projekt, PROJECT> NEW PROJECT?
  2. Wählen Sie aus dem Popup-Fenster AS3 PROJECT
  3. Benennen Sie Ihr Projekt. In meinem Fall Attraktor
  4. Wählen Sie Ihren Projektstandort

In diesem Handbuch finden Sie eine Einführung in FlashDevelop.


Schritt 4: Unterricht, den Sie brauchen

Es gibt 4 Klassen, die im Ordner erstellt werden können \ src \: Main.as, Vector2D.as, Ball.as und Math2.as. Es ist ratsam, dass Sie alle diese Dateien aus dem Quellpaket herunterladen und versuchen, sie anhand der Schritte abzubilden, um ein allgemeines Verständnis des Mechanismus zu erlangen, bevor Sie sie ändern. Ihre Rollen sind wie folgt ausgedrückt:

Klassenname Zweck der Organisation
Main.as Klasse, um die Bälle visuell zu erstellen und den Ereignissen Animation hinzuzufügen.
Vector2D Klasse, die alle Vektorbearbeitungsfunktionen enthält.
Ball Klasse, die Funktionen zur visuellen Erzeugung eines Balls enthält, implementiert Dynamik und Kinematik eines Balls.
Math2 Statische Klasse, die eine Funktion zur Vereinfachung der anfänglichen Anordnung von Bällen enthält.

Schritt 5: Randomisierung von Werten

Reden wir zuerst über die Math2-Klasse. Die folgende Funktion hilft, eine Zufallszahl innerhalb des angegebenen Bereichs zu generieren. Akzeptiert zwei Eingänge, minimale Grenze und maximale Grenze im Bereich.

 öffentliche statische Funktion randomiseBetween (range_min: int, range_max: int): int var range: int = range_max - range_min; var randomized: int = Math.random () * range + range_min; Rückkehr randomisiert; 

Schritt 6: Vector2D, Getter und Setter

Der größte Teil der verwendeten Mathematik befindet sich in Vector2D. Dieses Lernprogramm setzt bei den Benutzern ein gewisses Maß an Vertrautheit in der Vektoranalyse voraus. Die folgenden Funktionen werden im Allgemeinen verwendet, um Vektorkomponenten abzurufen und festzulegen sowie eine Methode zum Zurücksetzen aller Komponenten auf Null. Wenn Sie sich jedoch nicht mit Vektoren unwohl fühlen, besuchen Sie einen guten Beitrag über Euklidische Vektoren von Daniel Sidhion.

 öffentliche Funktion Vector2D (valueX: Number, valueY: Number) this._x = valueX; this._y = valueY;  public function set vecX (valueX: Number): void this._x = valueX;  public function get vecX (): Number return this._x öffentliche Funktionsgruppe vecY (valueY: Number): void this._y = valueY;  public function get vecY (): Number return this._y öffentliche Funktion setVector (valueX: Number, valueY: Number): void this._x = valueX; this._y = valueY;  public function reset (): void this._x = 0; this._y = 0; 

Schritt 7: Vector2D, Operationen

Die Hauptanwendungen von Vector2D liegen in den folgenden Funktionen:

  • erhalte die Größe des Vektors
  • erhalte den Winkel, der durch den Vektor in Bezug auf den Ursprung erstellt wurde
  • erhalte die Vektorrichtung des Vektors
  • einfache Vektoroperationen für Addition, Subtraktion und Skalar ausführen
    Multiplikation
 öffentliche Funktion getMagnitude (): Number var lengthX: Number = this._x; var lengthY: Number = this._y; return Math.sqrt (lengthX * lengthX + lengthY * lengthY);  public function getAngle (): Number var lengthX: Number = this._x; var lengthY: Number = this._y; return Math.atan2 (LängeY, LängeX);  public function getVectorDirection (): Vector2D var vectorDirection: Vector2D = new Vector2D (this._x / this.getMagnitude (), this._y / this.getMagnitude ()); return Vector2D (vectorDirection);  public function minusVector (vector2: Vector2D): void this._x - = vector2.vecX; this._y - = vector2.vecY;  public function addVector (vector2: Vector2D): void this._x + = vector2.vecX; this._y + = vector2.vecY;  public function multiply (scalar: Number): void this._x * = skalar; this._y * = Skalar; 

Schritt 8: Ball. Als Zeichnung

Das Ball In der Klasse finden alle interessanten Operationen statt. Um mit unserer Animation zu beginnen, müssen wir einen Ball zeichnen und verschiedene kinematik- und dynamikbezogene Variablen einstellen. Die Funktion zum Zeichnen eines Balls ist wie folgt:

 private Funktion draw (Radius: Anzahl, Farbe: uint): void graphics.beginFill (color, 1); graphics.drawCircle (0, 0, Radius); graphics.endFill (); 

Schritt 9: Ball.as private Variablen

Die erwähnten verschiedenen kinematischen und dynamikbezogenen Variablen sind wie folgt angegeben:

 private var _disp: Vector2D; // Verschiebungsvektor, relativ zum Ursprung private var _velo: Vector2D; // Geschwindigkeitsvektor private var _acc: Vector2D; // Beschleunigungsvektor private var _attractive_coeff: Number = 500; private var _mass: Anzahl;

Schritt 10: Ball. Als Initiation

Wenn der Konstruktor der Ball-Klasse aufgerufen wird, werden Grafiken gezeichnet. Nach dem Ziehen wird der Ball zufällig auf die Bühne gelegt. Wir werden auch die privaten Variablen festlegen. Alle Vektorgrößen werden auch bei 0 initialisiert, mit Ausnahme der Verschiebung, die relativ zum Ursprung gemessen wird.

 öffentliche Funktion Ball (Radius: Anzahl = 20, Farbe: uint = 0x0000FF) this.draw (Radius, Farbe); this._mass = Radius / 2; // Angenommen, die Masse ist der halbe Radius this.x = Math2.randomiseBetween (0, 550); this.y = Math2.randomiseBetween (0, 400); this._disp = new Vector2D (this.x, this.y); // Anfangsverschiebung einstellen this._velo = new Vector2D (0, 0); this._acc = new Vector2D (0, 0); 

Schritt 11: Ball. Als Anziehungskraft berechnen

Wir müssen die zugrunde liegende Kraft berechnen, durch die sich unsere Teilchen animieren lassen. Weißt du was, es ist die Schwerkraft. Die folgende Funktion hilft bei der Berechnung dieser Kraft. Beachten Sie, dass auf die Beschleunigung um eine Kappe angewendet wird 5. Die horizontalen und vertikalen Kraftkomponenten werden mittels Trigonometrie abgeleitet. Die obige Animation kann zum Verständnis der Mathematik beitragen.

 öffentliche Funktion get mass (): Number return _mass;  private Funktion getForceAttract (m1: Number, m2: Number, vec2Center: Vector2D): Vector2D / * berechnet die Anziehungskraft anhand der folgenden Formel: * F = K * m1 * m2 / r * r * / var numerator: Number = this._attractive_coeff * m1 * m2; var Nenner: Number = vec2Center.getMagnitude () * vec2Center.getMagnitude (); var forceMagnitude: Anzahl = Zähler / Nenner; var forceDirection: Number = vec2Center.getAngle (); // Setzen einer Obergrenze wenn (forceMagnitude> 0) forceMagnitude = Math.min (forceMagnitude, 5); // Ableiten der Kraftkomponente, horizontal, vertikal var forceX: Number = forceMagnitude * Math.cos (forceDirection); var forceY: Number = forceMagnitude * Math.sin (forceDirection); var force: Vector2D = new Vector2D (forceX, forceY); Rückkehr Kraft; 

Schritt 12: Ball. Als Beschleunigung berechnen

Sobald der Kraftvektor erhalten wurde, können wir die resultierende Beschleunigung berechnen. Merken, F = ma, so a = F / m.

 public function getAcc (vecForce: Vector2D): Vector2D // Einstellung der Beschleunigung durch Kraft var vecAcc: Vector2D = vecForce.multiply (1 / this._mass); return veccAcc; 

Schritt 13: Ball.as Displacement berechnen

Mit der berechneten Beschleunigung können wir die resultierende Verschiebung effektiv berechnen.

Denken Sie daran, dass die berechnete Kraft tatsächlich auf der Verschiebung zwischen der Mitte der Kugeln basiert.

 private Funktion getDispTo (Ball: Ball): Vector2D var currentVector: Vector2D = neuer Vector2D (Ball.x, Ball.y); currentVector.minusVector (this._disp); return currentVector;  public function attractedTo (Ball: Ball): void var toCenter: Vector2D = this.getDispTo (Ball); var currentForceAttract: Vector2D = this.getForceAttract (ball.mass, this._mass, toCenter); this._acc = this.getAcc (currentForceAttract); this._velo.addVector (this._acc); this._disp.addVector (this._velo); 

Schritt 14: Ball.as Werkzeugverschiebung

Dann können wir unseren Ball durch die unten stehende Funktion an seinen neuen Ort bringen. Beachten Sie, dass die berechnete Verschiebung niemals sofort an der aktuellen Position des Balls implementiert wird. Eine solche Konstruktion soll eine Überprüfung ermöglichen: Kollisionserkennung zwischen Kugeln.

 öffentliche Funktion setPosition (vecDisp: Vector2D): void this.x = Math.round (vecDisp.vecX); this.y = Math.round (vecDisp.vecY); 

Denken Sie daran, dass die Kraft auf der Entfernung zwischen den Mittelpunkten basiert. Daher dringen die Kugeln ein und bewegen sich weiter, da die Anziehungskraft höher ist, wenn sie näher sind. Wir müssen die Beschleunigung und die Geschwindigkeit auf 0 zurücksetzen, wenn die Kugeln sich gegenseitig berühren. Wir müssen jedoch ein Mittel zur Erkennung der Kollision zwischen zwei Kugeln erhalten.


Schritt 15: Ball.as Kollisionserkennung

Die Kollision kann leicht überprüft werden. Die Trennung zwischen zwei beliebigen Kugeln sollte nicht kleiner sein als die Summe ihrer Radien. Hier ist die Kollisionserkennungsfunktion:

 public function collisionInto (ball: Ball): Boolean var hit: Boolean = falsch; var minDist: Number = (ball.width + this.width) / 2; if (this.getDispTo (ball) .getMagnitude () < minDist)  hit = true;  return hit; 

Schritt 16: Ball.as Berechne den Platz, um sich zurückzuweisen

Normalerweise, wenn eine Kollision zwischen zwei Kugeln festgestellt wurde, überlappen sich ihre Zustände. Wir müssen sicherstellen, dass sie einfach am Rand sitzen und nicht überlappen. Wie? Wir können eine der Kugeln von der anderen weg verschieben, aber wir müssen zuerst die richtige Verschiebung berechnen. Hier ist die Verschiebungsberechnung:

 öffentliche Funktion getRepel (Ball: Ball): Vector2D var minDist: Number = (Ballbreite + this.breite) / 2; // Berechne den Abstand, um var abwehren zu können. Ball: Vector2D = this.getDispTo (ball); var directToBall: Vector2D = toBall.getVectorDirection (); directToBall.multiply (minDist); directToBall.minusVector (toBall); directToBall.multiply (-1); return directToBall; 

Schritt 17: Ball.as Gerätewechsel zur Abstoßung

Nachdem wir die richtige Verschiebung berechnet haben, müssen wir sie implementieren. Die Aktion ist wie das Abstoßen einer der Kugeln. Darüber hinaus müssen wir noch zwei zusätzliche Befehle ausführen. Denken Sie daran, wir haben ein dynamisches Umfeld. Selbst nachdem wir die Verschiebung der Kugel zur Kante eingestellt haben, wird sie durch die Beschleunigung und die resultierende Geschwindigkeit angeregt, was zu einer unerwünschten Bewegung des Hin- und Herbewegens führt. Wir müssen diese Werte für Beschleunigung und Geschwindigkeit auf Null zurücksetzen.

 öffentliche Funktion abgestoßenBy (Ball: Ball): void this._acc.reset (); this._velo.reset (); var repelDisp: Vector2D = getRepel (Kugel); this._disp.addVector (repelDisp); 

Schritt 18: Ball als animieren

Schließlich können wir unseren Ball animieren (Rendern), als ob er von einem anderen angezogen würde. Wenn eine Kollision erkannt wird, wird die Verschiebung so angepasst, dass sie nicht in die Kante eindringt. Dies geschieht zuerst für die Kugeln, wenn sie mit der Mitte kollidieren, und dann für die Kugeln, wenn sie miteinander kollidieren.

 public function animate (center: Ball, all: Array): void this.attractedTo (center); if (collisionInto (center)) this.repelledBy (center); für (var i: int = 0; i < all.length; i++)  var current_ball:Ball = all[i] as Ball; if (collisionInto(current_ball) && current_ball.name != this.name) this.repelledBy(current_ball);  this.setPosition(this._disp); 

Schritt 19: Main.as Private Variables

Weiter zu unserer letzten Klasse, Main. Die Hauptklasse wird zu Beginn des Projekts generiert. Zu den privaten Variablen gehören der eine Ball, der alle anderen anzieht, und die Anzahl der Bälle in unserer Flash-Präsentation.

 privater var mainBall: Kugel; private var totalBalls: int = 10;

Schritt 20: Main.as Draw Balls

Zuerst sollten wir die Bälle initialisieren. Es wird einen Hauptball geben, der alle anderen anzieht. Die anderen sind so benannt, dass die Referenzierung später einfach erfolgen kann.

 private Funktion createBalls (): void mainBall = neuer Ball (50, 0x00FF00); this.addChild (mainBall); für (var i: int = 0; i < this.totalBalls; i++)  var currentBall:Ball = new Ball(); currentBall.name = "ball" + i; this.addChild(currentBall);  

Schritt 21: Main.as Implementation Ball Interaction

Weisen Sie dann der Hauptkugel Ereignisse zu, damit sie beim Klicken ziehbar wird und beim Loslassen gestoppt wird.

 private Funktion init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // Einstiegspunkt createBalls (); mainBall.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown); stage.addEventListener (MouseEvent.MOUSE_UP, onMouseUp); animateAll ();  private Funktion onMouseUp (e: MouseEvent): void stopDrag ();  private Funktion onMouseDown (e: MouseEvent): void e.target.startDrag (); 

Schritt 22: Main.as Animated Balls

Animationsbälle, die vom Main angezogen werden. Jedem Ball ist ein EnterFrame-Ereignis zugeordnet.

 private Funktion animateAll (): void for (var i: uint = 0; i < totalBalls; i++)  //each ball is pulled by main_ball var current_ball:Ball = this.getChildByName("ball" + i) as Ball; current_ball.addEventListener(Event.ENTER_FRAME, enterFrame);   private function enterFrame(e:Event):void  var allObj:Array = new Array(); for (var i:int = 0; i <= totalBalls; i++)  var current_ball:Ball = this.getChildAt(i) as Ball; allObj.push(current_ball);  e.target.animate(mainBall, allObj); 

Schritt 23: Film testen

Drücken Sie anschließend Strg + Eingabetaste, um eine Vorschau der Animation anzuzeigen.


Fazit

Um dieses Tutorial noch einen Schritt weiter zu bringen, können Leser dieses Projekt durch die Implementierung anderer linearer Kräfte erweitern.

In jedem Fall sind Simulationen ein hervorragendes Werkzeug, um Ideen zu liefern, die in einer Physik-Unterrichtsumgebung durch Text und Bild schwer verständlich sind, insbesondere wenn sich der Zustand im Laufe der Zeit ändert.

Ich hoffe, dieses kleine Tutorial hilft dir irgendwie. Terima kasih (das ist "Danke" in Malaysia), dass Sie sich Zeit zum Lesen genommen haben und sich darauf freuen, Kommentare von anderen Lesern zu hören.