Ford's Circle

by phi16
♥0 | Line 101 | Modified 2015-02-03 00:53:52 | MIT License
play

ActionScript3 source code

/**
 * Copyright phi16 ( http://wonderfl.net/user/phi16 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kwAv
 */

package {
    import flash.geom.Matrix;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.Rectangle;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.ui.Mouse;
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.Sprite;
    public class Ford extends Sprite {
        public var rp:BitmapData=new BitmapData(465,465,true,0xff000000);
        public var mp:BitmapData=new BitmapData(465,465,true,0xff000000);
        public var rmp:Bitmap=new Bitmap(rp);
        public var bmp:Bitmap=new Bitmap(mp);
        public var spr:Sprite=new Sprite();
        public var bg:Sprite=new Sprite();
        public var r:Rectangle=new Rectangle(0,0,465,465);
        public var p:Point=new Point(0,0);
        public var mat:Array=[1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,0.9,0];
        public var cmt:ColorMatrixFilter=new ColorMatrixFilter(mat);
        public var scan:int=0;
        public function Ford(){
            spr.graphics.lineStyle(1,0xffffff);
            bg.graphics.lineStyle(1,0xffffff);
            this.addChild(rmp);
            this.addChild(bmp);
            addEventListener(Event.ENTER_FRAME,frame);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,mdn);
        }
        public function frame(e:Event):void{
            mp.applyFilter(mp,r,p,cmt);
            spr.graphics.clear();
            if(scan<465)draw(spr,false,scan);
            draw(spr,true,mouseX);
            mp.draw(spr);
            scan+=30;
            if(scan>2000)scan=Math.random()*30;
        }
        public function mdn(e:MouseEvent):void{
            bg.graphics.clear();
            draw(bg,false,mouseX);
            rp.draw(bg);
        }
        public function draw(s:Sprite,b:Boolean,m:Number):void{
            var f:Array=under10(approximate(m/465.0,5));
            var x:Number=f[0]/Number(f[1]);
            var y:Number=1/Number(2*f[1]*f[1]);
            var p:Number=x*465,q:Number=y*465,r:Number=y*465;
            if(b)s.graphics.lineStyle(1,getColor(x));
            else s.graphics.lineStyle(1,0xffffff);
            s.graphics.drawCircle(p,q,r);
            if(r<200)s.graphics.drawCircle(p,465-q,r);
            if(b && r<200){
                s.graphics.moveTo(p,0);
                s.graphics.lineTo(p,465);
            }
        }
        public function approximate(f:Number,n:int):Array{
            if(n==0 || f==0)return [];
            var c:int=1/f;
            var q:Array=approximate(1/f-c,n-1);
            q.unshift(c);
            return q;
        }
        public function under10(v:Array):Array{
            var a:Array=fromCf(v);
            if(a[1]>10){
                v.pop();
                return under10(v);
            }else return a;
        }
        public function fromCf(e:Array):Array{
            if(e.length==0)return [0,1];
            var p:int=e.shift();
            var q:Array=fromCf(e);
            e.unshift(p);
            q[0]+=q[1]*p;
            var r:int=q[1];q[1]=q[0];q[0]=r;
            return simplify(q);
        }
        public function simplify(v:Array):Array{
            var e:int=gcd(v[0],v[1]);
            return [v[0]/e,v[1]/e];
        }
        public function gcd(x:int,y:int):int{
            if(x==0)return y;
            else return gcd(y%x,x);
        }
        public function getColor(i:Number):int{
            var colr:int,colg:int,colb:int;
            var c:Number=0;
            colr=(Math.sin((i*360+c)*Math.PI/180)+1)*255/2;
            colg=(Math.sin((i*360+120+c)*Math.PI/180)+1)*255/2;
            colb=(Math.sin((i*360-120+c)*Math.PI/180)+1)*255/2;
            return colr*256*256+colg*256+colb;
        }
    }
}

Forked