forked from: Fourier Transform
/**
* Copyright hogefuga ( http://wonderfl.net/user/hogefuga )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3pyA
*/
// forked from phi16's Fourier Transform
package {
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.*;
public class Fourier extends Sprite {
private var spr:Sprite = new Sprite();
private var sz:Number = 465;
private var wz:Number = 400;
private var bs:Number = 20;
private var hei:Number = wz/Math.PI;
private var cy:Number = (hei/2-bs+sz-hei-bs)/2;
private var das:Array = new Array();
private var dir:Array = new Array();
private var i:int;
private var click:Boolean = false;
private var mt:int,my:Number;
private var tim:Number=0;
private var rads:Array = new Array();
private var iads:Array = new Array();
private var pss:Array = new Array();
private var dS:int = 256;
private var fS:int = 32;
private var func:String = "";
private var tf:TextField=new TextField();
private var txtIn:Boolean = false;
private var tick:int = 0;
private var parF:String = "";
public function Fourier() {
addChild(spr);
addEventListener(Event.ENTER_FRAME,step);
for(i=0;i<dS;i++){
das[i]=0;
dir[i]=Math.sin(i*2*Math.PI/dS);
if(i<fS){
rads[i]=iads[i]=0;
}
pss[i]=0;
}
tf.defaultTextFormat = new TextFormat("Tahoma",30,0x7f7f7f);
tf.x=10.0;
tf.y=0.0;
tf.height=0.0;
tf.antiAliasType = "advanced";
tf.text = "y = sin x";
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
dft();
addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
addEventListener(MouseEvent.MOUSE_UP,mouseUp);
addEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
}
public function step(e:Event):void{
spr.graphics.clear();
spr.graphics.beginFill(0);
spr.graphics.drawRect(0,0,sz,sz);
spr.graphics.endFill();
spr.graphics.lineStyle(2,0xffffff,0.5);
spr.graphics.moveTo(0,sz-hei-bs);
spr.graphics.lineTo(sz,sz-hei-bs);
spr.graphics.moveTo(0,sz-bs);
spr.graphics.lineTo(sz,sz-bs);
spr.graphics.moveTo(0,hei/2-bs);
spr.graphics.lineTo(sz,hei/2-bs);
spr.graphics.lineStyle(2,0xffffff,0.2);
spr.graphics.moveTo(sz/2-wz/2,sz-hei-bs);
spr.graphics.lineTo(sz/2-wz/2,sz-bs);
spr.graphics.moveTo(sz/2+wz/2,sz-hei-bs);
spr.graphics.lineTo(sz/2+wz/2,sz-bs);
spr.graphics.lineStyle(1,0xffffff,0.1);
spr.graphics.moveTo(sz/2-wz/4,sz-hei-bs);
spr.graphics.lineTo(sz/2-wz/4,sz-bs);
spr.graphics.moveTo(sz/2+wz/4,sz-hei-bs);
spr.graphics.lineTo(sz/2+wz/4,sz-bs);
spr.graphics.lineStyle(2,0xffffff,0.2);
spr.graphics.moveTo(sz/2,sz-hei-bs);
spr.graphics.lineTo(sz/2,sz-bs);
spr.graphics.moveTo(0,sz-hei/2-bs);
spr.graphics.lineTo(sz,sz-hei/2-bs);
spr.graphics.lineStyle(2,0xffffff,0.2);
spr.graphics.moveTo(sz/2,cy-hei/2);
spr.graphics.lineTo(sz,cy-hei/2);
spr.graphics.moveTo(sz/2,cy+hei/2);
spr.graphics.lineTo(sz,cy+hei/2);
spr.graphics.lineStyle(2,0xffffff,0.1);
spr.graphics.moveTo(hei*3/5,cy);
spr.graphics.lineTo(sz,cy);
spr.graphics.lineStyle(3,0x7fff7f,1);
spr.graphics.moveTo(-10,sz-hei/2-bs);
for(i=-30;i<dS+30;i++){
var t:int=(i+dS)%dS;
spr.graphics.lineTo(i*wz/dS+sz/2-wz/2,sz-hei/2-das[t]*hei/2-bs);
if(t>=0 && t<dS)das[i]+=(dir[i]-das[i])/2.0;
}
var px:Number = hei*3/5, py:Number = cy, pr:Number = hei/2;
var dx:Number = 0, dy:Number = 0;
spr.graphics.lineStyle(1,0xffffff,0.2);
spr.graphics.drawCircle(px,py,pr);
for(i=0;i<fS;i++){
spr.graphics.lineStyle(2,0xffffff,0.2);
spr.graphics.drawCircle(px+dx*pr,py-dy*pr,rads[i]*pr);
spr.graphics.lineStyle(2,0xffffff,0.5);
spr.graphics.moveTo(px+dx*pr,py-dy*pr);
dx += Math.cos(2*Math.PI*i*(tim+64)/256)*rads[i];
dy += Math.cos(2*Math.PI*i*tim/256)*rads[i];
spr.graphics.lineTo(px+dx*pr,py-dy*pr);
spr.graphics.lineStyle(2,0xffffff,0.2);
spr.graphics.drawCircle(px+dx*pr,py-dy*pr,iads[i]*pr);
spr.graphics.lineStyle(2,0xffffff,0.5);
spr.graphics.moveTo(px+dx*pr,py-dy*pr);
dx += Math.sin(2*Math.PI*i*(tim+64)/256)*iads[i];
dy += Math.sin(2*Math.PI*i*tim/256)*iads[i];
spr.graphics.lineTo(px+dx*pr,py-dy*pr);
}
spr.graphics.endFill();
spr.graphics.beginFill(0x00ff00,1);
spr.graphics.drawCircle(px+dx*pr,py-dy*pr,4);
spr.graphics.drawCircle(sz/2,py-dy*pr,2);
spr.graphics.endFill();
spr.graphics.lineStyle(3,0x00ff00,0.5);
pss.unshift(dy);
pss.pop();
spr.graphics.moveTo(px+dx*pr,py-dy*pr);
for(i=0;i<dS;i++){
spr.graphics.lineTo(sz/2+i/dS*sz/2,py-pss[i]*pr);
}
spr.graphics.lineStyle(1,0xffffff,1);
if(txtIn && tick % 30 < 15){
spr.graphics.moveTo(tf.width + tf.x, 5);
spr.graphics.lineTo(tf.width + tf.x, hei/2-bs-5);
}
if(txtIn)tick++;
else tick = 0;
tim+=1.6;
}
public function mouseDown(e:MouseEvent):void{
if(mouseY < hei/2-bs){
txtIn = true;
tf.textColor = 0xcfcfcf;
func = tf.text.substr(4);
return;
}else if(mouseY < sz-hei-bs)return;
tf.textColor = 0x7f7f7f;
txtIn = false;
click=true;
rewrite((mouseX-(sz/2-wz/2))/wz, -(mouseY+bs-(sz-hei/2))/(hei/2));
tf.text = "y = f(x)";
}
public function mouseMove(e:MouseEvent):void{
if(click){
rewriteLine((mouseX-(sz/2-wz/2))/wz, -(mouseY+bs-(sz-hei/2))/(hei/2));
tf.text = "y = f(x)";
}
}
public function mouseUp(e:MouseEvent):void{
click=false;
}
public function rewrite(x:Number,y:Number):void{
y=Math.min(Math.max(y,-1),1);
var t:int=(int)(x*dS)+dS;
dir[t%dS]=y;
mt=t,my=y;
dft();
}
public function rewriteLine(x:Number,y:Number):void{
y=Math.min(Math.max(y,-1),1);
var t:int=(int)(x*dS)+dS;
var fi:int,en:int;
if(mt == t){
rewrite(x,y);
return;
}else if(mt<t)fi=mt+1,en=t;
else if(mt>t)fi=t,en=mt-1;
for(var j:int=fi;j<=en;j++){
var a:Number = (j-mt)/(t-mt);
dir[(j+dS)%dS]=a*y+(1-a)*my;
}
mt=t,my=y;
dft();
}
public function dft():void{ //dir[] -> rads[], iads[]
var ds:Array = new Array(), es:Array = new Array();
for(i=0;i<dS;i++)ds[i]=dir[dS-i-1], es[i]=0;
DFT(ds,es,dS);
for(i=0;i<fS;i++){
rads[i]=ds[i]/dS*2;
iads[i]=es[i]/dS*2;
}
rads[0]/=2;
iads[0]/=2;
}
public function DFT(x:Array, y:Array, n:int):void{
if(n==1)return;
var x0:Array = new Array(), y0:Array = new Array();
var x1:Array = new Array(), y1:Array = new Array();
var j:int=0;
for(j=0;j<n/2;j++){
x0[j]=x[2*j];
y0[j]=y[2*j];
x1[j]=x[2*j+1];
y1[j]=y[2*j+1];
}
DFT(x0,y0,n/2);
DFT(x1,y1,n/2);
for(j=0;j<n;j++){
var zR:Number = Math.cos(2*Math.PI*j/n), zI:Number = Math.sin(2*Math.PI*j/n);
x[j] = x0[j%(n/2)] + zR * x1[j%(n/2)] - zI * y1[j%(n/2)];
y[j] = y0[j%(n/2)] + zR * y1[j%(n/2)] + zI * x1[j%(n/2)];
}
return;
}
public function keyDown(e:KeyboardEvent):void{
if(!txtIn)return;
var c:int = e.keyCode;
if(c == Keyboard.BACKSPACE && func.length!=0)func=func.slice(0,func.length-1);
else if(c == Keyboard.ENTER)runParse();
else if(c == 186 && e.shiftKey)func=func+"*";
else if(c == 189 && !e.shiftKey)func=func+"-";
else if(c == 187 && e.shiftKey)func=func+"+";
else if(c == 191 && !e.shiftKey)func=func+"/";
else if(c == 222 && !e.shiftKey)func=func+"^";
else if(48<=c && c<=57 && !e.shiftKey)func=func+String.fromCharCode(c);
else if(c == 53 && e.shiftKey)func=func+"%";
else if(c == 56 && e.shiftKey)func=func+"(";
else if(c == 57 && e.shiftKey)func=func+")";
else if(65<=c && c<=90)func=func+String.fromCharCode(c + 32);
tf.text = "y = " + func;
}
public function runParse():void{
//var ast: = Parser();
}
}
}