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
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
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
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.
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.
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.
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 SÍ hice un diagrama de fuerzas. Y la masa no influye.
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.
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