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!
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.
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:
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.
Die Implementierung erfolgt in der FlashDevelop-IDE. Erstellen Sie Ihre Projektdatei.
In diesem Handbuch finden Sie eine Einführung in FlashDevelop.
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. |
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;
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;
Die Hauptanwendungen von Vector2D liegen in den folgenden Funktionen:
ö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;
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 ();
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;
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);
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;
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;
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);
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.
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;
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;
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);
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);
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;
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);
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 ();
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);
Drücken Sie anschließend Strg + Eingabetaste, um eine Vorschau der Animation anzuzeigen.
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.