package { import fl.motion.BezierEase; import flash.display.Sprite; import flash.display.StageDisplayState; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.ui.Mouse; import flash.utils.Dictionary; import net.vis4.color.PerceptualColor; import net.vis4.geom.delaunay.Delaunay; import net.vis4.geom.delaunay.Edge; import net.vis4.geom.delaunay.XYZ; import net.vis4.geom.delaunay.Triangle; import net.vis4.geom.isolines.IsoLines; import net.vis4.layout.FullScreenApp; import net.vis4.text.fonts.embedded.TitilliumMaps; import net.vis4.text.Label; import net.vis4.utils.NumberUtil; /** * ... * @author gka */ [SWF(width="800", height="600", backgroundColor="#000000", frameRate="31")] public class Main extends FullScreenApp { private var _points:Array = []; private var _values:Dictionary; private var _triangles:Array = []; private var _edges:Array; public function Main():void { Mouse.hide(); //stage.displayState = StageDisplayState.FULL_SCREEN; //stage.addEventListener(MouseEvent.MOUSE_MOVE, run); //stage.addEventListener(Event.RESIZE, reset); reset(); // load weather data } private function reset(e:Event = null):void { randomPoints(50); triangulate(); run(); } private function run(e:Event = null):void { graphics.clear(); randomValues(); drawPoints(); var t0:Number = new Date().time; // trace('took ' + (new Date().time - t0) + ' ms to calculate delaunay triangulation'); t0 = new Date().time; drawTriangles(); isolines(); } private function randomValues():void { _values = new Dictionary(); var peak:Point = new Point(stage.stageWidth*Math.random(), stage.stageHeight*Math.random()); var i:uint = 0; for each (var p:Point in _points) { i++; _values[p] = 400 + Math.random() * 5 + Math.sin(i / 50 * Math.PI) * 50 - Point.distance(peak, p); } } private function randomPoints(num:uint):void { _points = []; for (var i:uint = 0; i < num; i++) { var p:Point = new Point(15+Math.round(Math.random() * (stage.stageWidth-30)), 15+Math.round(Math.random() * (stage.stageHeight - 30))); _points.push(p); } _points.sortOn('x', Array.NUMERIC); } private function drawPoints():void { graphics.clear(); graphics.beginFill(0xffffff, 1); for each (var p:Point in _points) { graphics.drawRect(p.x - 0, p.y - 0, 2, 2); var l:Label = new Label(Math.round(_values[p]), new TitilliumMaps({color: 0xffffff, size: 8, alpha:.3})); l.x = p.x- l.width/2; l.y = p.y+2; addChild(l); } graphics.endFill(); } private function triangulate():void { _triangles = Delaunay.triangulate(_points); } private function drawTriangles():void { graphics.lineStyle(0, 0xFBE28C, .2); for each (var t:Triangle in _triangles) { graphics.moveTo(_points[t.p1].x, _points[t.p1].y); graphics.lineTo(_points[t.p2].x, _points[t.p2].y); graphics.lineTo(_points[t.p3].x, _points[t.p3].y); graphics.lineTo(_points[t.p1].x, _points[t.p1].y); } graphics.lineStyle(); } private function isolines():void { var il:IsoLines = new IsoLines(_points, _triangles, _values); var vmin:Number = Number.MAX_VALUE, vmax:Number = Number.MIN_VALUE; for each (var v:Number in _values) { vmin = Math.min(vmin, v); vmax = Math.max(vmax, v); } vmin = NumberUtil.ceilToFactor(vmin, 10); vmax = NumberUtil.floorToFactor(vmax, 10); // trace(vmin, vmax); for (v = vmin; v <= vmax; v += 80) { // trace(v); var isoline:Array = il.isoline(v); drawIsoline(v, PerceptualColor.fromHSL(260 + (v-vmin)/(vmax-vmin)*160, 1, .3 + (v-vmin)/(vmax-vmin)*.3).intColor, isoline); } } private function drawIsoline(v:Number, color:uint, lines:Array):void { graphics.lineStyle(3, color, .8); //graphics.beginFill(color, 1); for each (var line:Array in lines) { if (line.length < 2) continue; graphics.moveTo(line[0].x, line[0].y); for (var i:uint = 1; i < line.length; i++) { //graphics.drawCircle(line[i].x, line[i].y, 6); //graphics.curveTo(line[i].x, line[i].y, line[i + 1].x, line[i + 1].y); graphics.lineTo(line[i].x, line[i].y); //graphics.moveTo(line[i + 1].x, line[i + 1].y); } var l:Label = new Label(v, new TitilliumMaps({ color: color, size: 10, alpha: .9 })); l.x = line[0].x + 2; l.y = line[0].y + 2; addChild(l); } graphics.lineStyle(); } private function init(e:Event = null):void { } } }