Spanish (Español) translation by Muhamad Zulfiqor (you can also view the original English article)
El estudio de las fuerzas es de interés central en la dinámica, el estudio de las causas del movimiento y cambios en el movimiento. Fuerza de la gravedad es un ejemplo; Esto es lo que hace que los satélites que giran alrededor de planetas y nosotros permanecer en la tierra.
En este tutorial, será construir una simulación de tal fenómeno y ser capaz de observar, experimentar y jugar con las partículas en la escena.
Entre todas las partículas generadas, una partícula principal atraerá a otros. Como estas partículas se mueven hacia el principal, los usuarios pueden hacer clic en esta partícula principal para arrastrar, haciendo que estas partículas redirigir su rumbo. Estas partículas detienen como chocan con el borde de la bola principal, pero no superponen.
La estructura de este tutorial se arregla de una manera donde una breve teoría en física de entrega antes de introducir la aplicación de la simulación. ¡Disfrute!
Vista previa del resultado final
Veamos el resultado final que vamos a trabajar hacia:
Haga clic y arrastre el círculo verde grande para moverlo alrededor y ver cómo reaccionan los pequeños círculos azules.
Paso 1: Fuerza gravitacional, fórmula



En primer lugar, un prefacio de física. La fuerza de atracción gravitacional entre cualquier dos objetos se expresa mediante la siguiente fórmula:
F: atractivo fuerza se ejerce sobre el objeto del interés (p2)
una partícula arbitraria (p1).
G: constante gravitacional de
M1: masa de p1
m2: masa de p2
r: distancia entre p1 y p2
Tome nota especial de los siguientes:
- La relación entre gravedad y distancia: F es inversamente proporcional al cuadrado de la distancia que separa las dos partículas. Esto significa que el más cercano A y B son entre sí, mayor será la fuerza de atracción entre ellas y viceversa. Si duplicar la distancia, la fuerza va hacia abajo a un cuarto de su valor original.
- Valor de la constante gravitacional, G, es científicamente 6.67259 x 10-11 N * m2 / kg2. Sin embargo, 500 se sustituye este valor en el entorno de Flash.
- Nos podemos relacionar con la anchura de las partículas su masa. Para este ejemplo, yo he definido la masa de la partícula para ser la mitad de su radio.
Paso 2: La 2 º ley de Newton, ecuación
Para traducir fuerza en cinemática, es necesario calcular la aceleración de la partícula. A continuación se muestra la ecuación famosa de Sir Isaac Newton:



F: fuerza gravitacional ejerciéndose en objeto de interés (p2)
m: masa del objeto de interés (p2)
a: aceleración del objeto de interés (p2) bajo influencia de F
Aquí, la implicación es que la fuerza mayor aplicada sobre resultados de la partícula A en una aceleración mayor (suponiendo que su masa permanece igual). Esta aceleración cambiará la velocidad de la partícula.
Paso 3: A partir de proyecto
Implementación se hará en IDE FlashDevelop. Crear el archivo de proyecto.
- Iniciar un nuevo proyecto, proyecto > nuevo proyecto...
- Seleccione de la ventana emergente, PROYECTO AS3
- Nombre de tu proyecto. En mi caso, atractor
- Seleccione la ubicación del proyecto
Consulte a esta guía para obtener una introducción a FlashDevelop.
Paso 4: Clases que necesita
Hay 4 clases para crear en la carpeta \src\: Main.as, Vector2D.as, Ball.as y Math2.as. Es recomendable que descargue todos estos archivos desde el paquete fuente y tratar de mapa contra pasos para llegar a obtener una comprensión general del mecanismo antes de modificarlas. Sus funciones se expresan como abajo:
Nombre de la clase | Propósito de la organización |
Main.as | Clase para crear visualmente las bolas y poner animación para eventos. |
Vector2D | Clase que contiene todas las funciones de manipulación de vectores. |
Bola | Clase que contiene las funciones para generar visualmente una bola, implementa dinámica y cinemática de una bola. |
Math2 | Clase estática que contiene una función para facilitar la asignaron al azar a la ubicación inicial de las bolas. |
Paso 5: Valores que asignaron al azar
Permite hablar de la clase Math2 primera. La función de abajo le ayudará a generar un número aleatorio dentro del rango especificado. Acepta dos entradas, límite mínimo y límite máximo en la gama.
public static function randomiseBetween(range_min:int, range_max:int):int { var range:int = range_max - range_min; var randomised:int = Math.random() * range + range_min; return randomised; }
Paso 6: Vector2D, Getters y Setters
La mayor parte de las matemáticas que utiliza está situada en Vector2D. Este tutorial asume un nivel de familiaridad en el análisis de vectores en los usuarios. Las funciones a continuación se usan generalmente para obtener y configurar componentes vectoriales, más un método para restablecer todos los componentes a cero. En cualquier caso, si no se siente cómodo con Vectores, visite un gran post sobre Vectores Euclidianos de Daniel Sidhion.
public function 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 } public function set vecY(valueY:Number):void { this._y = valueY; } public function get vecY():Number { return this._y } public function setVector(valueX:Number, valueY:Number):void { this._x = valueX; this._y = valueY; } public function reset():void { this._x = 0; this._y = 0; }
Paso 7: Vector2D, Operaciones
Los principales usos de Vector2D se encuentran en las siguientes funciones, que:
- obtener la magnitud del vector
- obtener el ángulo de vectores en relación con el origen
- obtener la dirección del vector del vector
- realizar operaciones de simple vector de la suma, resta y escalar
multiplicación
public function 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(lengthY, lengthX); } 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 *= scalar; this._y *= scalar; }
Paso 8: Dibujo de Ball.as
La clase bola es donde todas las operaciones interesantes. Para comenzar nuestra animación, necesitamos dibujar una bola y diversas variables relacionadas con la cinemática y la dinámica. La función para dibujar una bola es como a continuación:
private function draw(radius:Number, color:uint) :void { graphics.beginFill(color, 1); graphics.drawCircle(0, 0, radius); graphics.endFill(); }
Paso 9: Variables de Ball.as privado
El mencionado que varias variables relacionados con la cinemática y dinámica se indican como abajo:
private var _disp:Vector2D; //displacement vector, relative to the origin private var _velo:Vector2D; //velocity vector private var _acc:Vector2D; //acceleration vector private var _attractive_coeff:Number = 500; private var _mass:Number;
Paso 10: Ball.as iniciación
Como se llama el constructor de clase de la bola, se dibujan gráficos. Una vez dibujado, el balón se colocará en el escenario al azar. También estableceremos las variables privadas. Todas las cantidades vectoriales también se inicializarán a 0, excepto el desplazamiento que se mide en relación con el origen.
public function Ball(radius:Number = 20, color:uint = 0x0000FF) { this.draw(radius, color); this._mass = radius / 2; //assuming mass is half of radius this.x = Math2.randomiseBetween(0, 550); this.y = Math2.randomiseBetween(0, 400); this._disp = new Vector2D(this.x, this.y); //set initial displacement this._velo = new Vector2D(0, 0); this._acc = new Vector2D(0, 0); }
Paso 11: Ball.as calcular la fuerza de atracción
Tenemos que calcular la fuerza subyacente que causa nuestras partículas animar. Adivina qué, es la fuerza gravitacional. La función siguiente ayudará en el cálculo de esta fuerza. Tenga en cuenta que un casquillo se aplica en la aceleración en 5. Los componentes horizontales y verticales de la fuerza se derivan usando trigonometría; la animación de arriba puede ayudar en la comprensión de las matemáticas de esto.
public function get mass():Number { return _mass; } private function getForceAttract (m1:Number, m2:Number, vec2Center:Vector2D):Vector2D { /* calculate attractive force based on the following formula: * F = K * m1 * m2 / r * r */ var numerator:Number = this._attractive_coeff * m1 * m2; var denominator:Number = vec2Center.getMagnitude() * vec2Center.getMagnitude(); var forceMagnitude:Number = numerator / denominator; var forceDirection:Number = vec2Center.getAngle(); //setting a cap if (forceMagnitude > 0) forceMagnitude = Math.min(forceMagnitude, 5); //deriving force component, horizontal, vertical var forceX:Number = forceMagnitude * Math.cos(forceDirection); var forceY:Number = forceMagnitude * Math.sin(forceDirection); var force:Vector2D = new Vector2D(forceX, forceY); return force; }
Paso 12: Ball.as calcular aceleración
Una vez obtenido el vector de fuerza, podemos calcular la aceleración resultante. Recuerda que F = ma, por lo tanto a = F/m.
public function getAcc(vecForce:Vector2D):Vector2D { //setting acceleration due to force var vecAcc:Vector2D = vecForce.multiply(1 / this._mass); return veccAcc; }
Paso 13: Ball.as calcular el desplazamiento
Calculadas la aceleración, podemos calcular efectivamente el desplazamiento resultante.
Recuerde que la fuerza calculado realmente se basa en el desplazamiento entre el centro de las bolas.
private function getDispTo(ball:Ball):Vector2D { var currentVector:Vector2D = new 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); }
Paso 14: Aplicar Ball.as desplazamiento
Entonces, somos capaces de mover la bola a su nueva ubicación, a través de la función siguiente. Tenga en cuenta que los desplazamiento calculado nunca se implementa en la ubicación actual de la pelota inmediatamente. Tal diseño debe permitir comprobar hacer: detección de colisiones entre bolas.
public function setPosition(vecDisp:Vector2D):void { this.x = Math.round(vecDisp.vecX); this.y = Math.round(vecDisp.vecY); }
Recuerde que la fuerza se basa en la distancia entre centros. Por lo tanto, las bolas se penetran y continúe moviendo debido a la fuerza de atracción es mayor cuando están más cerca. Tenemos que restablecer la aceleración y la velocidad a 0 cuando las bolas toquen el borde. Sin embargo, necesitamos obtener un medio de detectar la colisión entre dos bolas.
Paso 15: Detección de colisiones Ball.as
Colisión puede comprobarse fácilmente. Separación entre las dos bolas no debe ser menor que la suma de sus radios. Esta es la función de detección de colisión:
public function collisionInto (ball:Ball):Boolean { var hit:Boolean = false; var minDist:Number = (ball.width + this.width) / 2; if (this.getDispTo(ball).getMagnitude() < minDist) { hit = true; } return hit; }
Paso 16: Ball.as calcular desplazar para repeler



Generalmente cuando se detecte una colisión entre dos bolas, su estado está superponiéndose unos a otros. Tenemos que asegurarnos que solo sientan bien en el borde y no se superponen. ¿Cómo? Nos podemos desplazar a una de las bolas de la otra, pero tenemos que calcular el desplazamiento derecha para ajustar el primero. Aquí está el cálculo del desplazamiento:
public function getRepel (ball:Ball): Vector2D { var minDist:Number = (ball.width + this.width) / 2; //calculate distance to repel var toBall:Vector2D = this.getDispTo(ball); var directToBall:Vector2D = toBall.getVectorDirection(); directToBall.multiply(minDist); directToBall.minusVector(toBall); directToBall.multiply( -1); return directToBall; }
Paso 17: Ball.as implementar desplazamiento para repeler



Después hemos calculado el desplazamiento derecha, tenemos que aplicarlo. La acción es como rechazar a una de las bolas. Además, tenemos que hacer otro dos comandos adicionales. Recuerde, estamos tratando con un ambiente dinámico. Incluso después de que hemos establecido el desplazamiento de la bola en el borde, aceleración debido a la fuerza y la velocidad resultante animará, causando un movimiento indeseable de mover de un tirón hacia adentro y hacia afuera. Necesitamos restablecer estos valores de aceleración y la velocidad a cero.
public function repelledBy(ball:Ball):void { this._acc.reset(); this._velo.reset(); var repelDisp:Vector2D = getRepel(ball); this._disp.addVector(repelDisp); }
Paso 18: Ball.as Animate
Por último, nos podemos animar (render) la bola como si era sentirse atraído por otro. Cuando se detecta la colisión, desplazamiento será ajustado para que no penetrará el borde. Esto sucederá primero las bolas cuando chocan con el centro y luego las bolas cuando chocan uno con el otro.
public function animate(center:Ball, all:Array):void { this.attractedTo(center); if (collisionInto(center)) this.repelledBy(center); for (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); }
Paso 19: Main.as privado Variables
Pasar a nuestra última clase, principal. Clase principal se genera en el inicio del proyecto. Variables privadas incluirán la uno bola que atrae a todos los demás y el número de bolas en nuestra presentación en Flash.
private var mainBall:Ball; private var totalBalls:int = 10;
Paso 20: Sorteo Main.as bolas
En primer lugar, debemos inicializar bolas. Habrá una bola principal que atraen a todos los demás. Los demás se nombran para que referencia puede hacer fácilmente más adelante.
private function createBalls ():void { mainBall = new Ball(50, 0x00FF00); this.addChild(mainBall); for (var i:int = 0; i < this.totalBalls; i++) { var currentBall:Ball = new Ball(); currentBall.name = "ball" + i; this.addChild(currentBall); } }
Paso 21: Implementar Main.as bola interacción
A continuación, asignar eventos a la bola principal hacerlo arrastrarse cuando hace clic en detener cuando se libera.
private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point createBalls(); mainBall.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); animateAll(); } private function onMouseUp(e:MouseEvent):void { stopDrag(); } private function onMouseDown(e:MouseEvent):void { e.target.startDrag(); }
Paso 22: Main.as animados bolas
Animación de bolas que están siendo atraídos por la principal. Un evento EnterFrame se asigna a cada bola.
private function 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); }
Paso 23: Probar película
Finalmente, presiona Ctrl + Enter para previsualizar la animación.
la conclusión
Para llevar este tutorial un paso más allá, los lectores pueden extender este proyecto implementando otras fuerzas lineales.
En cualquier caso, las simulaciones sirven como una gran herramienta para entregar ideas difíciles de explicar con texto e imagen en un entorno de aula de Física, especialmente cuando el estado cambia con el tiempo.
Espero que este pequeño tutorial te ayude de alguna manera. Terima Kasih (que es 'gracias' en Malasia) por tomarse el tiempo de leer y esperar escuchar los comentarios de otros lectores.