Catmull-Rom Spline

by phi16
Visualize
♥0 | Line 117 | Modified 2015-03-12 01:16:59 | 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/21wz
 */

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;
    public class CurveDraw extends Sprite {
        public var tx:Number=465/2.0;
        public var ty:Number=465/2.0;
        public var list:Array=new Array();
        public var spr:Sprite=new Sprite();
        public var trac:Array=new Array();
        public var circ:Sprite=new Sprite();
        public var timer:int=0;
        public var mn:Array=new Array();
        public var i:int=0,ph:int=0;
        public function CurveDraw(){
            addChild(spr);
            for(i=0;i<3;i++){
                trac[i]=new Sprite();
                trac[i].blendMode="lighten";
                addChild(trac[i]);
            }
            circ.blendMode="lighten";
            addChild(circ);
            addEventListener(Event.ENTER_FRAME,step);
        }
        public function step(e:Event):void{
            spr.graphics.clear();
            circ.graphics.clear();
            spr.graphics.beginFill(0);
            spr.graphics.drawRect(0,0,465,465);
            spr.graphics.endFill();
            if(mn.length>0){
                spr.graphics.moveTo(mn[0].x,mn[0].y);
                for(i=1;i<mn.length;i++){
                    spr.graphics.lineStyle(8,grayScale(i/600.0));
                    spr.graphics.lineTo(mn[i].x,mn[i].y);
                }
            }
            for(i=3;i<list.length;i++){
                spr.graphics.lineStyle(2,grayScale((i as Number)/list.length));
                spr.graphics.drawCircle(list[i].x,list[i].y,5);
            }
            spr.graphics.lineStyle(2,0xffffff);
            if(list.length>0){
                spr.graphics.drawCircle(list[list.length-1].x,list[list.length-1].y,5);
            }

            if(timer%30==0){
                list.push(new Point(mouseX,mouseY));
                if(list.length>6)list.shift();
                ph++;
                for(i=0;i<3;i++)drawTrace(i);
                timer=0;
            }
            timer++;
            circ.graphics.lineStyle(0);
            var cx:Number,cy:Number;
            for(i=0;i<3;i++){
                trac[i].alpha=(Math.cos((timer-i*30.0+15)/45.0*Math.PI)+1)/2;
                cx=spline(list[i].x,list[i+1].x,list[i+2].x,list[i+3].x,timer/30.0+1-i);
                cy=spline(list[i].y,list[i+1].y,list[i+2].y,list[i+3].y,timer/30.0+1-i);
                circ.graphics.beginFill(0);
                circ.graphics.drawCircle(cx,cy,10);
                circ.graphics.endFill();
            }
            for(i=0;i<3;i++){
                trac[i].alpha=(Math.cos((timer-i*30.0+15)/45.0*Math.PI)+1)/2;
                cx=spline(list[i].x,list[i+1].x,list[i+2].x,list[i+3].x,timer/30.0+1-i);
                cy=spline(list[i].y,list[i+1].y,list[i+2].y,list[i+3].y,timer/30.0+1-i);
                circ.graphics.lineStyle(4,getColor(ph+i,i==1?1-timer/30.0:0),Math.min(trac[i].alpha*2,1));
                circ.graphics.drawCircle(cx,cy,10);
                if(i==1)mn.push(new Point(cx,cy));
            }
            if(mn.length>200)mn.shift();
        }
        public function drawTrace(i:int):void{
            trac[i].graphics.clear();
            trac[i].graphics.beginFill(0);
            trac[i].graphics.drawRect(0,0,465,465);
            trac[i].graphics.endFill();
            trac[i].graphics.lineStyle(8,getColor(ph+i,0));
            var x0:Number=list[i].x;
            var x1:Number=list[i+1].x;
            var x2:Number=list[i+2].x;
            var x3:Number=list[i+3].x;
            var y0:Number=list[i].y;
            var y1:Number=list[i+1].y;
            var y2:Number=list[i+2].y;
            var y3:Number=list[i+3].y;
            trac[i].graphics.moveTo(spline(x0,x1,x2,x3,-3),spline(y0,y1,y2,y3,-3));
            for(var t:Number=-1.9;t<=3;t+=0.1){
                trac[i].graphics.lineTo(spline(x0,x1,x2,x3,t),spline(y0,y1,y2,y3,t));
            }
        }
        public function spline(x0:Number,x1:Number,x2:Number,x3:Number,t:Number):Number{
            var v0:Number=(x2-x0)*0.5;
            var v1:Number=(x3-x1)*0.5;
            return (2*x1-2*x2+v0+v1)*t*t*t+(-3*x1+3*x2-2*v0-v1)*t*t+v0*t+x1;
        }
        public function getColor(i:Number,br:Number):int{
            var colr:int,colg:int,colb:int;
            var c:Number=90;
            var num:int=12;
            colr=(Math.sin((i*360/num+c)*Math.PI/180)+1)*255/2;
            colg=(Math.sin((i*360/num+120+c)*Math.PI/180)+1)*255/2;
            colb=(Math.sin((i*360/num-120+c)*Math.PI/180)+1)*255/2;
            colr=255*br+colr*(1.0-br);
            colg=255*br+colg*(1.0-br);
            colb=255*br+colb*(1.0-br);
            return colr*256*256+colg*256+colb;
        }
        public function grayScale(v:Number):int{
            var col:int=v*255;
            col=Math.max(Math.min(col,255),0);
            return col*256*256+col*256+col;
        }
    }
}