CatmullRomSpark
CatmullRom曲線
参考:
http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
// forked from miyaoka's forked from: CatmullRom曲線
// forked from Nao_u's CatmullRom曲線
//
// CatmullRom曲線
//
// 参考:
// http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
//
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.filters.*;
import flash.utils.Timer;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class CatmullRomMain extends Sprite {
public function CatmullRomMain() {
var bg:Shape = new Shape();
CANVAS = new Shape();
var mtr:Matrix = new Matrix();
mtr.createGradientBox(SCREEN_W*2, SCREEN_H*2, 0, -SCREEN_W/2, -SCREEN_H/2);
bg.graphics.beginGradientFill(
GradientType.RADIAL,
[0x0, 0xffffff],
[1, 1],
[90, 255],
mtr
);
bg.graphics.drawRect(0, 0, SCREEN_W, SCREEN_H);
addChild(bg);
BMD = new BitmapData(SCREEN_W, SCREEN_H, true, 0x00000000);
addChild(new Bitmap(BMD));
addChild(CANVAS);
//init
var cr:CatmullRom = new CatmullRom
(
new Point( -SCREEN_W, SCREEN_H / 2),
new Point(0, SCREEN_H / 2),
new Point(SCREEN_W * 1.1, SCREEN_H / 2),
new Point(SCREEN_W * 2, SCREEN_H / 2)
);
cr.draw();
var center:Point = new Point(SCREEN_W / 2, SCREEN_H / 2);
//evt
// stage.addEventListener(MouseEvent.MOUSE_MOVE, function ():void
addEventListener(Event.ENTER_FRAME, function ():void
{
var dist:Number = Point.distance(new Point(mouseX, mouseY), new Point(SCREEN_W / 2, SCREEN_H / 2));
var num:Number = (1 - dist / SCREEN_W* 2)
var count:Number = num * 20;
cr.innerPts = new Vector.<Point>;
num = Math.max(0.05, Math.pow(num, 3));
while (cr.innerPts.length < count)
{
var pt:Point = Point.polar(Math.random() * SCREEN_W * 0.7 * num, Math.random() * Math.PI * 2).add(center);
cr.innerPts.splice(cr.innerPts.length * Math.random(), 0, pt)
}
cr.draw();
BMD.unlock();
});
var timer:Timer = new Timer(50);
timer.addEventListener(TimerEvent.TIMER, function ():void
{
BMD.lock();
BMD.applyFilter(BMD, BMD.rect, new Point(), new BlurFilter(20, 20));
BMD.colorTransform(BMD.rect, new ColorTransform(0.3,1.0,1.0, 0.95));
});
timer.start();
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
var SCREEN_W:Number = 465, SCREEN_H:Number = 465;
var CANVAS:Shape;
var BMD:BitmapData;
class CatmullRom{
public var innerPts:Vector.<Point> = new Vector.<Point>;
public var stOuterPt:Point;
public var stInnerPt:Point;
public var endInnerPt:Point;
public var endOuterPt:Point;
public function CatmullRom(stOuterPt:Point, stInnerPt:Point, endInnerPt:Point, endOuterPt:Point) {
this.stOuterPt = stOuterPt;
this.stInnerPt = stInnerPt;
this.endInnerPt = endInnerPt;
this.endOuterPt = endOuterPt;
}
public function draw():void{
var t:Number = 0;
var DivNum:int = (innerPts.length + 1) * 10;
var tAdd:Number = 1 / DivNum;
stInnerPt = new Point(0, (Math.random() - 0.5) *0.005 * SCREEN_H + SCREEN_H / 2);
endInnerPt = new Point(SCREEN_W *1.1, (Math.random() - 0.5) *0.005 * SCREEN_H + SCREEN_H / 2);
var pt:Point = getPosition( 0.0 );
var g:Graphics = CANVAS.graphics;
g.clear();
g.lineStyle(2, 0xffffff, 0.5);
g.moveTo(pt.x, pt.y);
for( var lp:int = 0; lp < DivNum; lp++,t += tAdd ){
pt = getPosition( t );
g.lineTo(pt.x, pt.y);
}
BMD.draw(CANVAS);
}
public function getPosition( t:Number ):Point{
var ret:Point = new Point();
var pts:Vector.<Point> = Vector.<Point>([stOuterPt, stInnerPt]).concat(innerPts).concat(Vector.<Point>([endInnerPt, endOuterPt]));
var div:Number = (1 / (innerPts.length + 1));
var idx:int = t / div;
var tt:Number = (t - div * idx) / div;
ret.x = catmullRom( pts[idx].x, pts[idx+1].x, pts[idx+2].x, pts[idx+3].x, tt)
ret.y = catmullRom( pts[idx].y, pts[idx+1].y, pts[idx+2].y, pts[idx+3].y, tt)
return ret;
}
public function catmullRom( x0:Number, x1:Number, x2:Number, x3:Number, t:Number ):Number{
var v0:Number = (x2 - x0) / 2.0;
var v1:Number = (x3 - x1) / 2.0;
var t2:Number = t * t;
var t3:Number = t2 * t;
return ( 2.0 * x1 - 2.0 * x2 + v0 + v1 ) * t3 + ( -3.0 * x1 + 3.0 * x2 - 2.0 * v0 - v1 ) * t2 + v0 * t + x1;
}
}