Sierpinski distortion
by Petri Leskinen, Espoo, Finland 5 February 2009
http://pixelero.wordpress.com
package {
/*
* by Petri Leskinen, Espoo, Finland 5 February 2009
* http://pixelero.wordpress.com
*
*/
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.TriangleCulling;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
public class Sierpinski extends Sprite {
// (new SomeImage(400,300)) as BitmapData;
protected var w:int,
h:int, bmp:BitmapData,
vertices:Vector.<Number>,
indices:Vector.<int>,
uvtData:Vector.<Number>,
spr:Sprite,
tick:Number =0.0,
running:Boolean;
protected const DEGREES120:Number = Math.PI/3;
internal var i:int, tmp:Number;
function Sierpinski() {
init();
}
function init():void {
w = stage.stageWidth-100;
h = w*Math.sqrt(3)/2; // regular triangle: height=0.866*width
bmp = new BitmapData(w,h,false,0x00);
// perlinNoise for seed, could actually be any kind of image data
bmp.perlinNoise(w,h,4,12,false,true,7,false);
// darken the image
bmp.draw(bmp,new Matrix(),
new ColorTransform(0.5,0.5,0.5,1,0,0,0));
addChild(spr = new Sprite());
spr.x = 0.5*(stage.stageWidth -w); // centered
spr.y = 0.5*(stage.stageHeight -h);
stage.addEventListener(MouseEvent.CLICK, toggleAnimation);
toggleAnimation();
}
// a click on canvas will pause
function toggleAnimation(e:MouseEvent=null):void {
if (running =!running) addEventListener(Event.ENTER_FRAME, render)
else removeEventListener(Event.ENTER_FRAME, render);
}
function render(e:Event=null):void {
tick += 0.05;
vertices = Vector.<Number>([
w/2,0, // top triangle
w/4,h/2,
0.75*w,h/2,
w/4,h/2, // Left bottom triangle
0.0,h,
w/2,h,
0.75*w,h/2,// Right bottom triangle
w/2,h,
w,h
] );
// a perspective transformation,
// Math.sin in t-coordinate does the distortion
uvtData = Vector.<Number>([
0.5,0.0, 1.0 +0.9*Math.sin(tmp=tick),
0.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120),
1.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120),
0.5,0.0, 1.0 +0.9*Math.sin(tmp=0.5*tick) ,
0.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120),
1.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120),
0.5,0.0, 1.0 +0.9*Math.sin(tmp=0.2*tick) ,
0.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120),
1.0,1.0, 1.0 +0.9*Math.sin(tmp+=DEGREES120)
]);
/* Vector.<Number>([ // uvtData for a regular Sierpinski
0.5,0.0, 1.0 ,
0.0,1.0, 1.0 ,
1.0,1.0, 1.0 ,
0.5,0.0, 1.0 ,
0.0,1.0, 1.0 ,
1.0,1.0, 1.0 ,
0.5,0.0, 1.0 ,
0.0,1.0, 1.0 ,
1.0,1.0, 1.0
]);
*/
indices = Vector.<int>([
0,1,2,
3,4,5,
6,7,8
]);
var bmpTemp:BitmapData = new BitmapData(w,h,false,0xFFFFFF); // background color
// Iterations, five times
for (i = 0; i<5;i++) {
with (spr.graphics) {
clear();
beginBitmapFill( i==0 ? bmp : bmpTemp ,
null, // no matrix
true, // = repeat
true);
drawTriangles(vertices,
indices,
uvtData,
TriangleCulling.NONE);
endFill();
}
bmpTemp.draw(spr);
}
}
/////////////////////////////////
}
}