Resonance in damped harmonic oscillator
Resonance in damped harmonic oscillator.
@see http://wonderfl.net/code/fbed60b8d4628ee9bdf8c915501971cd3f862bf0
package {
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
/**
* Resonance in damped harmonic oscillator.
* @see http://wonderfl.net/code/fbed60b8d4628ee9bdf8c915501971cd3f862bf0
*/
public class DHO extends Sprite {
private var b:Number;
//private var x:Number;
private var v:Number;
private var tmax:Number;
private var tstep:Number;
private var xcanvas:Graphics;
private var vcanvas:Graphics;
private var ecanvas:Graphics;
public function DHO () {
var xc:Shape = new Shape; addChild (xc); xcanvas = xc.graphics;
var vc:Shape = new Shape; addChild (vc); vcanvas = vc.graphics;
var ec:Shape = new Shape; addChild (ec); ecanvas = ec.graphics;
addEventListener (Event.ENTER_FRAME, loop);
w0t = 0;
}
private var w:Number;
private var w0:Number, w0t:Number;
private function loop (e:Event):void {
w0t += 0.01; if (w0t > 6.283185307179586) w0t -= 6.283185307179586;
var phi:Number = 6.283185307179586 * mouseY / 465
// x for frequency
w = 0.001 + 9.999 * mouseX / 465;
// mark x of natural frequency w0
w0 = 3.0 - 2.5 * Math.cos (w0t);
graphics.clear ()
graphics.lineStyle (0);
graphics.moveTo (46.5 * w0, 0);
graphics.lineTo (46.5 * w0, 465);
b = 0.1;
x = Math.cos (phi);
v = Math.sin (phi);
tmax = 30;
animate ();
}
private function animate ():void {
var df:int = 2;
var xold:Array = new Array (df);
var xnew:Array = new Array (df);
var t:Number = 0.0;
xold[0] = this.x;
xold[1] = this.v;
xcanvas.clear ();
xcanvas.lineStyle (0, 255); // positin in blue
vcanvas.clear ();
vcanvas.lineStyle (0, 255 * 256); // velocity in green
ecanvas.clear ();
ecanvas.lineStyle (0, 255 * 65536); // energy in red
this.tstep = (0.05 * 1.0 / (1.0 +
/* originally this.delay here, slider 0..100, 42 is good value */ 42
/ 50.0));
var i:int, j:int, numsteps:int = int(this.tmax / this.tstep + 0.5);
for (i = 1; i <= numsteps; ++i) {
//for (j = 0; j < df; ++j)
// xnew[j] = RKstep (xold, 6.283185307179586 * t, 6.283185307179586 * this.tstep) [j];
xnew = RKstep (xold, 6.283185307179586 * t, 6.283185307179586 * this.tstep);
var scale:Number = 465 / tmax, offset:Number = 465 / 2;
xcanvas.moveTo (scale * t, offset + scale * xold[0]);
xcanvas.lineTo (scale * (t + this.tstep), offset + scale * xnew[0]);
vcanvas.moveTo (scale * t, offset + scale * xold[1]);
vcanvas.lineTo (scale * (t + this.tstep), offset + scale * xnew[1]);
ecanvas.moveTo (scale * t, offset + scale * (xold[0] * xold[0] + xold[1] * xold[1]) / 2.0);
ecanvas.lineTo (scale * (t + this.tstep), offset + scale * (xnew[0] * xnew[0] + xnew[1] * xnew[1]) / 2.0);
t += this.tstep;
for (j = 0; j < df; ++j)
xold[j] = xnew[j];
}
}
private function RKstep (xx:Array, tt:Number, ttstep:Number):Array {
var len:int = xx.length;
var coefs:Array = [ 0.0, 0.5, 0.5, 1.0 ];
var nums:Array = [ 1.0, 2.0, 2.0, 1.0 ];
var xxnew:Array = new Array (len);
var arg:Array = new Array (len);
var A:Array = new Array (len);
var j:int, k:int;
for (j = 0; j < len; ++j) {
xxnew[j] = xx[j];
A[j] = 0.0;
}
for (k = 0; k < 4; ++k) {
var tval:Number = tt + coefs[k] * ttstep;
for (j = 0; j < len; ++j) {
arg[j] = (xx[j] + coefs[k] * A[j]);
}
for (j = 0; j < len; ++j) {
A[j] = (ttstep * f (arg, tval)[j]);
xxnew[j] += nums[k] * A[j] / 6.0;
}
}
return xxnew;
}
private function f (xx:Array, tt:Number):Array {
var ff:Array = new Array (xx.length);
ff[0] = xx[1];
ff[1] = Math.sin(w*tt) - w0 * w0 * xx[0] - (2.0 * this.b * w0 * xx[1]);
return ff;
}
}
}