package { /** * @author nicoptere * http://en.nicoptere.net/ */ import flash.events.*; import flash.display.*; import fl.controls.Button; public class Main extends MovieClip { //to draw the delaunay triangulation public var tab:Array; //to draw the voronoi diagram public var vclip:Sprite; private var drawVoronoi:Boolean = false; private var animate:Boolean = false; public function Main() { stage.scaleMode = StageScaleMode.NO_SCALE; vclip = new Sprite(); addChild( vclip ); init(); var voronoiBtn:Button = new Button(); voronoiBtn.label = 'voronoi scheme'; voronoiBtn.addEventListener( MouseEvent.CLICK, voronoiBtnClickHandler ); addChild( voronoiBtn ); var animateBtn:Button = new Button(); animateBtn.label = 'make things move !'; animateBtn.width = 150; animateBtn.addEventListener( MouseEvent.CLICK, animateBtnClickHandler ); animateBtn.x = voronoiBtn.width; addChild( animateBtn ); } public function init():void { var w:int = stage.stageWidth; var h:int = stage.stageHeight; tab = new Array(); //pushes the corners var i:int; var x:Number; var y:Number; var off:int = 0; var p:Point; /* // grid shape var numx:int = 10; var numy:int = 10; tab.push( new Point( 0,0 ), new Point( w,0 ), new Point( w,h ), new Point( 0,h ) ); for ( i = 0; i < numx; i++ ) { for ( var j:int = 0; j < numy; j++ ) { x = 2*off + ( ( w / numx ) * i ) + ( Math.random() - .5 ) * off; y = 2*off + ( ( h / numy ) * j ) + ( Math.random() - .5 ) * off; p = new Point( x,y ); tab.push( p ); } } */ tab = []; p = new Point( w/2,h/2 ); tab.push( p ); var step:Number = 20; var ang:Number = ( Math.PI *2 / step ); var radius:Number = 200; for ( i = 0; i < step; i++ ) { x = w/2 + Math.cos( ang * i ) * radius; y = h/2 + Math.sin( ang * i ) * radius; p = new Point( x,y ); tab.push( p ); } for ( i = 0; i < step/2; i++ ) { x = w/2 + Math.cos( ang*2 * i ) * radius/2; y = h/2 + Math.sin( ang*2 * i ) * radius/2; p = new Point( x,y ); tab.push( p ); } render(); stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler ); } public function voronoiBtnClickHandler( e:Event ):void { drawVoronoi = !drawVoronoi ? true : false; render(); } public function animateBtnClickHandler( e:Event ):void { animate = !animate ? true : false; if( animate ) { addEventListener(Event.ENTER_FRAME, enterFrameHandler ); }else{ removeEventListener(Event.ENTER_FRAME, enterFrameHandler ); } } private function mouseDownHandler ( e:MouseEvent ):void { if(e.target is Button )return; var deletion:Boolean = false; var dx:Number; var dy:Number; var dist:Number; //if we click within a 5 pixels radius of an existing point, delete the point for ( var i:int = 0; i < tab.length; i++ ) { var p:Point = tab[ i ] as Point; dx = p.x - mouseX; dy = p.y - mouseY; dist = Math.sqrt( dx*dx + dy*dy ); if( dist < 5 ) { tab.splice( i, 1); deletion = true; } } if( !deletion )tab.push( new Point( mouseX, mouseY ) ); render(); } private function enterFrameHandler ( e:Event ):void { for ( var i:int = 0; i < tab.length; i++ ) { var p:Point = tab[ i ] as Point; p.x += ( Math.random() - .5 ) * 2; p.y += ( Math.random() - .5 ) * 2; } render(); } private function render():void { graphics.clear(); vclip.graphics.clear(); var delaunay:Array = Delaunay.Triangulate( tab ); //draws the Delaunay triangulation if( !drawVoronoi ) { var t:Triangle; var i:int; var L:int = delaunay.length; graphics.lineStyle( 2, 0x006699, .5); for ( i = 0; i < L; i++ ) { t = ( delaunay[ i ] as Triangle ); graphics.moveTo(t.p1.x, t.p1.y); graphics.lineTo(t.p2.x, t.p2.y); graphics.lineTo(t.p3.x, t.p3.y); graphics.lineTo(t.p1.x, t.p1.y); } } else { Voronoi.draw( delaunay, vclip.graphics ); } } } }