[Flash 9+]

September 2016

Original image

Result

Click on the image below (Flash) to generate new variations

The idea comes from overwatch title screen

Test project

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.net.LocalConnection;
	
	public class Main extends Sprite
	{
		[Embed(source = "asset/map960.png")]
		private const MapClass:Class;
		
		private const WIDTH:uint = 960;
		private const HEIGHT:uint = 477;
		private var result:Bitmap;
		
		public function Main()
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			// entry point
			stage.addEventListener(MouseEvent.CLICK, onClickStage);
			
			onClickStage();
		}
		
		private function onClickStage(e:MouseEvent = null):void
		{
			if (result)
			{
				removeChild(result);
				result.bitmapData.dispose;
				result = null;
				
				forceGC();
			}
			result = DelaunayEffect(new MapClass() as Bitmap);
			addChild(result);
		}
		
		/**
		 * return the bitmap with a new effect applyied on it
		 * @param	pBitmap
		 * @return
		 */
		private function DelaunayEffect(pBitmap:Bitmap, nbPoints:int = 96):Bitmap
		{
			// create the main container
			var container:Sprite = new Sprite();
			var bitmap:Bitmap = pBitmap;
			container.addChild(bitmap);
			
			// create random Point in space
			var sh:Shape = new Shape();
			var pts:Vector.<Point> = new Vector.<Point>;
			for (var i:int = 0; i &lt; nbPoints; i++)
			{
				pts.push(new Point(Math.random() * WIDTH, Math.random() * HEIGHT));
			}
			pts.push(new Point(0, 0));
			pts.push(new Point(WIDTH, 0));
			pts.push(new Point(WIDTH, HEIGHT));
			pts.push(new Point(0, HEIGHT));
			
			// triangulate and overlay
			var dl:Delaunay = new Delaunay();
			dl.render(sh.graphics, pts, dl.compute(pts));
			container.addChild(sh);
			sh.blendMode = BlendMode.OVERLAY;
			
			// store the result
			var dat:BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0x0);
			dat.draw(container);
			
			// add some noise
			var noiseDat:BitmapData = new BitmapData(WIDTH, HEIGHT, true, 0x0);
			noiseDat.noise(0, 192, 255, 0, true);
			dat.draw(noiseDat, null, new ColorTransform(1, 1, 1, 1 / 3, 0, 0, 0, 0), BlendMode.MULTIPLY);
			noiseDat.dispose();
			noiseDat = null;
			container = null;
			
			// clean
			bitmap.bitmapData.dispose();
			bitmap.bitmapData = dat;
			
			return bitmap;
		}
		
		private function forceGC():void
		{
			try
			{
				new LocalConnection().connect('foo');
				new LocalConnection().connect('foo');
			}
			catch (e:*)
			{
			}
		}
	
	}

}

A slighly modified version of Delaunay.ashttp://wonderfl.net/c/4cr7

package
{
	/**
	 * ...
	 * @author nicolas barradeau
	 */
	import flash.display.Graphics;
	import flash.geom.Point;
	
	public class Delaunay
	{
		static public var EPSILON:Number = Number.MIN_VALUE;
		static public var SUPER_TRIANGLE_RADIUS:Number = 1000000000;
		private var indices:Vector.<int>;
		private var circles:Vector.<Number>;
		
		public function compute(points:Vector.<Point>):Vector.<int>
		{
			var nv:int = points.length;
			if (nv < 3) return null;
			var d:Number = SUPER_TRIANGLE_RADIUS;
			points.push(new Point(0, -d), new Point(d, d), new Point(-d, d));
			indices = Vector.<int>([points.length - 3, points.length - 2, points.length - 1]);
			circles = Vector.<Number>([0, 0, d]);
			var edgeIds:Vector.<int> = new Vector.<int>();
			var i:int, j:int, k:int, id0:int, id1:int, id2:int;
			for (i = 0; i < nv; i++)
			{
				for (j = 0; j < indices.length; j += 3)
				{
					if (circles[j + 2] > EPSILON && circleContains(j, points[i]))
					{
						id0 = indices[j];
						id1 = indices[j + 1];
						id2 = indices[j + 2];
						edgeIds.push(id0, id1, id1, id2, id2, id0);
						indices.splice(j, 3);
						circles.splice(j, 3);
						j -= 3;
					}
				}
				for (j = 0; j < edgeIds.length; j += 2)
				{
					for (k = j + 2; k < edgeIds.length; k += 2)
					{
						if ((edgeIds[j] == edgeIds[k] && edgeIds[j + 1] == edgeIds[k + 1]) || (edgeIds[j + 1] == edgeIds[k] && edgeIds[j] == edgeIds[k + 1]))
						{
							edgeIds.splice(k, 2);
							edgeIds.splice(j, 2);
							j -= 2;
							k -= 2;
							if (j < 0) break;
							if (k < 0) break;
						}
					}
				}
				for (j = 0; j < edgeIds.length; j += 2)
				{
					indices.push(edgeIds[j], edgeIds[j + 1], i);
					computeCircle(points, edgeIds[j], edgeIds[j + 1], i);
				}
				edgeIds.length = 0;
				
			}
			id0 = points.length - 3;
			id1 = points.length - 2;
			id2 = points.length - 1;
			for (i = 0; i < indices.length; i += 3)
			{
				if (indices[i] == id0 || indices[i] == id1 || indices[i] == id2 || indices[i + 1] == id0 || indices[i + 1] == id1 || indices[i + 1] == id2 || indices[i + 2] == id0 || indices[i + 2] == id1 || indices[i + 2] == id2)
				{
					indices.splice(i, 3);
					i -= 3;
					continue;
				}
			}
			points.pop();
			points.pop();
			points.pop();
			return indices;
		}
		
		private function circleContains(circleId:int, p:Point):Boolean
		{
			var dx:Number = circles[circleId] - p.x;
			var dy:Number = circles[circleId + 1] - p.y;
			return circles[circleId + 2] > dx * dx + dy * dy;
		}
		
		private function computeCircle(points:Vector.<Point>, id0:int, id1:int, id2:int):void
		{
			var p0:Point = points[id0];
			var p1:Point = points[id1];
			var p2:Point = points[id2];
			var A:Number = p1.x - p0.x;
			var B:Number = p1.y - p0.y;
			var C:Number = p2.x - p0.x;
			var D:Number = p2.y - p0.y;
			var E:Number = A * (p0.x + p1.x) + B * (p0.y + p1.y);
			var F:Number = C * (p0.x + p2.x) + D * (p0.y + p2.y);
			var G:Number = 2.0 * (A * (p2.y - p1.y) - B * (p2.x - p1.x));
			var x:Number = (D * E - B * F) / G;
			circles.push(x);
			var y:Number = (A * F - C * E) / G;
			circles.push(y);
			x -= p0.x;
			y -= p0.y;
			circles.push(x * x + y * y);
		}
		
		public function render(graphics:Graphics, points:Vector.<Point>, indices:Vector.<int>):void
		{
			var shades:Array = [0x333333, 0x666666, 0x777777, 0x888888, 0x999999, 0xAAAAAA];
			var nbShades:int = shades.length;
			
			var id0:uint, id1:uint, id2:uint;
			for (var i:int = 0; i < indices.length; i += 3)
			{
				id0 = indices[i];
				id1 = indices[i + 1];
				id2 = indices[i + 2];
				graphics.beginFill(shades[int(Math.random() * nbShades)], 1);
				graphics.moveTo(points[id0].x, points[id0].y);
				graphics.lineTo(points[id1].x, points[id1].y);
				graphics.lineTo(points[id2].x, points[id2].y);
				graphics.lineTo(points[id0].x, points[id0].y);
			}
		}
	}

}

Vote in HexoSearch