¿Quieres registrarte?

Cómo crear un péndulo realista en ActionScript 3

Por: Juanlu_001
15 de Enero del 2009
7,118 visitas

En este tip vamos crear un objeto que oscile como un péndulo de manera realista utilizando ecuaciones físicamente coherentes en ActionScript 3. Aunque la explicación de esas ecuaciones no viene al caso, diré que están basadas en una aproximación y que no son ni mucho menos exactas, ya que requerirían conocimientos avanzados de cálculo diferencial para poder obtenerlas. No obstante, la aproximación es bastante buena y no se pierde un ápice de realismo.

Para comenzar, vamos a crear un documento nuevo de AS3 y vamos a dibujar nuestro péndulo en posición vertical, es decir, con el origen de coordenadas arriba en el centro. Ponemos la velocidad de fotogramas a 30, aunque en realidad puedes escoger el valor que más te convenga. Después de ajustar el punto de registro en el lugar donde queremos que esté el punto de rotación, le damos el nombre de instancia pendulo y escribimos este código en el único fotograma de la línea de tiempo:

Código :

import flash.events.Event.ENTER_FRAME;

addEventListener(Event.ENTER_FRAME, onEnterFrame);

with ( pendulo )
{
const g:Number = 9.8 * 300; // g = 9,8 m/s*s * 300 px/m
var t:Number = 0; // t = 0s
var l:Number = pendulo.height; // l = altura px
var phi = pendulo.rotation * Math.PI / 180; // phi = 0 rad
var omega = 0; // omega = 0 rad/s
}

function onEnterFrame(e:Event):void
{
with(pendulo)
{
t = 1 / 30; // t = 1 / 30 s porque 30 es la velocidad de fotogramas por segundo
phi = rotation * Math.PI / 180;
omega += ((-g * t) / l) * Math.sin(phi);
phi += omega * t;
rotation = phi * 180 / Math.PI;
}
}


Y ya está. Ya he dicho que en principio no explicaré las ecuaciones; si alguien tiene curiosidad puede preguntar en los comentarios. Ahora si giramos levemente nuestro péndulo y probamos nuestra película:



Pero claro, esto va a estar moviéndose hasta el día del juicio final por la tarde. Ahora podemos añadir un comportamiento que "empuje" el péndulo al hacer click, y rozamiento con el aire (que es proporcional al cuadrado de la velocidad):

Código :

import flash.events.Event.ENTER_FRAME;
import flash.events.MouseEvent.CLICK;

addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.CLICK, onClick);

with ( pendulo )
{
const g:Number = 9.8 * 300; // g = 9,8 m/s*s * 300 px/m
var t:Number = 0; // t = 0s
var l:Number = pendulo.height; // l = altura px
var phi = pendulo.rotation * Math.PI / 180; // phi = 0 rad
var omega = 0; // omega = 0 rad/s

var signo:int;
var drag:Number;
}

function onClick(e:MouseEvent):void
{
with(pendulo)
{
omega -= Math.PI * 1.5;
}
}

function onEnterFrame(e:Event):void
{
with(pendulo)
{
t = 1 / 30; // t = 1 / 30 s porque 30 es la velocidad de fotogramas por segundo
signo = (omega < 0) ? -1 : 1;
drag = omega * omega / 300;
phi = rotation * Math.PI / 180;
omega += ((-g * t) / l) * Math.sin(phi) - signo * drag;
phi += omega * t;
rotation = phi * 180 / Math.PI;
}
}


Y ahora sí, si publicamos la película:



¡Ya lo tenemos! Fácil, rápido y para toda la familia :)

Espero que os sea útil, ¡saludos!

 


También te interesa


Etiquetas flash actionscript fisica

Comentarios | Enviar un comentario
Ahora tengo que decir una cosa (no quería ensuciar el tip con esto). Aunque lo tenía en mente desde hacía meses, el hecho de que mi tutorial sobre cómo hacer un péndulo en AS1 resultara el segundo más visitado de Clab me recordó que había que mejorarlo con urgencia. No sé cómo cuando lo publiqué no fui fulminado por los cielos, pero lo cierto es que, si alguien lo ha visto, ese péndulo ni es realista ni tiene nada de física (¿vieron alguna vez un péndulo que se frenase así?). Además es una chapuza :roll:

Por eso, en calidad de autor de ese tutorial (y aunque sé que hay muchos enlaces apuntando a él) querría pedir que, si es posible, se cambiaran algunas cosas:


  • Que la primera frase cambiara de ser así:

    Yo :

    Como su título indica, esta escrito con el propósito de dar una manera sistemática de hacer que objetos tales como péndulos o similares oscilen de una manera realista, dando además multitud de posibilidades, como la de frenarse o no con el paso del tiempo o la de poder dar varias vueltas sobre el punto de rotación sin perder el efecto de realismo.
    a ser así:

    Yo :

    Como su título indica, esta escrito con el propósito de dar una manera sistemática de hacer que objetos tales como péndulos o similares oscilen, dando además multitud de posibilidades, como la de frenarse o no con el paso del tiempo o la de poder dar varias vueltas sobre el punto de rotación.

  • Que se escriba una advertencia visible de que este tip existe (que creo que es mucho mejor)


Nada más; muchas gracias a todos y disculpen las molestias.

P.D. ¡¡Y Dios, que algún moderador benévolo ponga mi código bien!! siempre me equivoco de etiqueta :'(
Por: Juanlu_001
Tag [as]
Por: Zah
Solo decir que la aproximación de la función sinus es considerada eso: una aproximación.
Se acepta porque para amplitudes de oscilación pequeñas se aproxima mucho, pero si fuese real, real, real, la ecuación de movimiento habría que sacarla de un diagrama de fuerzas, donde obviamente el péndulo tendría que tener masa.

Referente al Movimiento amortiguado, no veo tus matemáticas. Revisa esto:
Física en Flash: Movimieento Armónico Inframortiguado (se que no es AS3 y que el código da asco, pero te haces la idea).
Por: Bleend
Bleend dijo: "pero si fuese real, real, real, la ecuación de movimiento habría que sacarla de un diagrama de fuerzas, donde obviamente el péndulo tendría que tener masa."
Si depende de la masa estamos realmente jodidos, jodidos. Vale, fuera de bromas. Lo bueno de una simularión por ordenador es que no tenemos que integrar ecuaciones diferenciales.
Si tenemos que
d(w/2)=dt*sqrt(g*(sin^2(w0/2)-sin(w/2)/l)

Si pensamos en dt como los fps y d(w/2) como lo que avanza en ángulos podríamos escribir

Código :


function onEnterFrame(e:Event):void 

{

    var angulo_mitad:Number=pendulo.rotation*Math.PI/180;

var inc_mitad:Number=Math.sqrt(g*(Math.(sin(w0/2)*Math.sin(w0/2)-sin(angulo_mitad)*Math.sin(angulo_mitad))/l)

pendulo.rotation+=(angulo_mitad*2)*180/Math.PI

}



A eso ya le podríamos poner la fuerza de rozamiento si quisiéramos.
Por: Eliseo2
quería decir

Código :


pendulo.rotation+=(inc_mitad*2)*180/Math.PI



Por: Eliseo2
excelente pendulo
Por: jose.sosa

Bleend :

Solo decir que la aproximación de la función sinus es considerada eso: una aproximación.
Se acepta porque para amplitudes de oscilación pequeñas se aproxima mucho, pero si fuese real, real, real, la ecuación de movimiento habría que sacarla de un diagrama de fuerzas, donde obviamente el péndulo tendría que tener masa.

Referente al Movimiento amortiguado, no veo tus matemáticas. Revisa esto:
Física en Flash: Movimieento Armónico Inframortiguado (se que no es AS3 y que el código da asco, pero te haces la idea).


Querido Bleend, vayamos por partes:


  1. Bleend :

    Solo decir que la aproximación de la función sinus es considerada eso: una aproximación.
    Yo en mi aproximación me refería a que, al comenzar escribiendo las ecuaciones, tenemos que:



    Lo que pasa es que el 2º miembro no lo podemos integrar así como así, porque alfa es una función que depende también de t, y que no conocemos. Lo que pasa es que como vamos a tomar incrementos de tiempo suficientemente pequeños (1 / 30 segundos) podemos considerarlo constante y sacarlo fuera de la ecuación.

  2. Esto va también con el punto 2:

    Bleend :

    [...] si fuese real, real, real, la ecuación de movimiento habría que sacarla de un diagrama de fuerzas, donde obviamente el péndulo tendría que tener masa.


    Creo que puedes ver, en la ecuación anterior:



    Que hice un diagrama de fuerzas. Y la masa no influye.

  3. Bleend :

    [...] Referente al Movimiento amortiguado, no veo tus matemáticas. Revisa esto:
    Física en Flash: Movimieento Armónico Inframortiguado (se que no es AS3 y que el código da asco, pero te haces la idea).


    Si nos vamos a la Ecuación del arrastre o rozamiento experimentado por el cuerpo al desplazarse inmerso en un fluido:



    Vemos que tiene varias constantes, y que es directamente proporcional al cuadrado de la velocidad. Lo que pasa es que yo no fui sustituyendo cada una de las constantes por su valor, bien, me lo inventé un poco; pero aun así conserva esa proporcionalidad importante.

    Es más, la que está mal es la tuya.



Nada más que añadir, un saludo.
Por: Juanlu_001
Cierto, Bleend. La función que tu pusiste se refiere al amortiguamiento de ondas. El rozamiento (drag)depende de la velocidad cuando la velocidad es pequeña (en fluidos densos) y del cuadrado de la velocidad en el aire.

La ecuación que tu pusiste se refiere al amortiguamiento de ondas.


Y en cuanto a los ángulos, utiliza aproximaciones de ángulos pequeños (para la fórmula del periodo del péndulo, cos X = 1- X^2/2), y con una amplitud de menos de 10º, la diferencia prácticamente no se puede medir.
Por: Zah
Cierto, fallo mio :P (As ever...)
Por: Bleend
esta buenisima esta parte de programacion
Por: Eduart -blog
En este péndulo se está usando una ecuación de un movimiento armónico simple o algo así?

No sé, es que me dio esa sensación... y recuerdo oír en clase de física que los péndulos hacen M.A.S. en oscilaciones pequeñas.


Aún así, está bastante bien xD
Por: nestorrente-blog

nestorrente-blog :

En este péndulo se está usando una ecuación de un movimiento armónico simple o algo así?


Qué va :P

La ecuación del MAS no me servía, porque quería un efecto realista para oscilaciones grandes también.
Por: Juanlu_001
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.