In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Icosphere

Icosphere is an approximation of a sphere based on an icosahedron. The trianglar faces are created by splitting each triangle into four triangles connecting the mid-points of the edges. By repeating this process, the icosphere becomes more precise. In icosphere, five faces meet at the original vertices of the icosahedron, while six meet at the other vertices.

This sample is based on Andreas Kahler's C# code. He also provides more detailed explanation on his web page.
http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html
Get Adobe Flash player
by k__ 13 Jan 2011
/**
 * Copyright k__ ( http://wonderfl.net/user/k__ )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/dmmu
 */

package {
	import flash.display.*;
	import flash.geom.*;
	import flash.events.*;

	public class Main extends Sprite {
		private var canvas:Sprite;
		private var vertexes:Vector.<Vector3D>;
		private var faces:Vector.<Array>;
		private var cache:Object;
		private var fl:Number=50;
		private var zoom:Number=10;
		private var viewPointZ:Number=-200;
		private var radius:Number=50;
		private var yRot:Number=0;
		private var xRot:Number=0;
		private var count:uint=0;

		public function Main() {
			initGraphics();
			cache = new Object();
			createIcosphere();
			addEventListener(Event.ENTER_FRAME, h_enterFrame);
		}

		private function initGraphics():void {
			graphics.beginFill(0);
			graphics.drawRect(0,0,stage.stageWidth, stage.stageHeight);
			graphics.endFill();

			addChild(canvas = new Sprite());
			canvas.x=stage.stageWidth/2;
			canvas.y=stage.stageHeight/2;
		}

		private function createIcosphere(recursion:uint = 0):void {
			vertexes=new Vector.<Vector3D>  ;
			faces=new Vector.<Array>  ;
			//cache = new Object();

			var t:Number = (1.0 + Math.sqrt(5.0)) / 2.0;

			addVertex(-1,  t,  0);
			addVertex( 1,  t,  0);
			addVertex(-1, -t,  0);
			addVertex( 1, -t,  0);

			addVertex( 0, -1,  t);
			addVertex( 0,  1,  t);
			addVertex( 0, -1, -t);
			addVertex( 0,  1, -t);

			addVertex( t,  0, -1);
			addVertex( t,  0,  1);
			addVertex(-t,  0, -1);
			addVertex(-t,  0,  1);

			faces.push([0, 11, 5]);
			faces.push([0, 5, 1]);
			faces.push([0, 1, 7]);
			faces.push([0, 7, 10]);
			faces.push([0, 10, 11]);

			faces.push([1, 5, 9]);
			faces.push([5, 11, 4]);
			faces.push([11, 10, 2]);
			faces.push([10, 7, 6]);
			faces.push([7, 1, 8]);

			faces.push([3, 9, 4]);
			faces.push([3, 4, 2]);
			faces.push([3, 2, 6]);
			faces.push([3, 6, 8]);
			faces.push([3, 8, 9]);

			faces.push([4, 9, 5]);
			faces.push([2, 4, 11]);
			faces.push([6, 2, 10]);
			faces.push([8, 6, 7]);
			faces.push([9, 8, 1]);


			for (var i:uint = 0; i < recursion; i++) {
				var faces2:Vector.<Array> = new Vector.<Array>();
				for (var j:uint = 0; j < faces.length; j ++) {
					var a:uint=getMiddlePoint(faces[j][0],faces[j][1]);
					var b:uint=getMiddlePoint(faces[j][1],faces[j][2]);
					var c:uint=getMiddlePoint(faces[j][2],faces[j][0]);
					faces2.push([faces[j][0], a, c]);
					faces2.push([faces[j][1], b, a]);
					faces2.push([faces[j][2], c, b]);
					faces2.push([a, b, c]);
				}
				faces=faces2;
			}
		}

		private function addVertex(_x:Number, _y:Number, _z:Number):uint {
			var v:Vector3D=new Vector3D(_x,_y,_z);
			v.normalize();
			v.scaleBy(radius);
			vertexes.push(v);
			return vertexes.length - 1;
		}

		private function getMiddlePoint(i1:uint, i2:uint):uint {
			var firstIsSmaller:Boolean=i1<i2;
			var smallerIndex:uint=firstIsSmaller?i1:i2;
			var greaterIndex:uint=firstIsSmaller?i2:i1;
			var key:Number = (smallerIndex << 32) + greaterIndex;

			if (cache["i"+key]) {
				return cache[key];
			}

			var p1:Vector3D=vertexes[i1];
			var p2:Vector3D=vertexes[i2];

			var index:uint = addVertex((p1.x + p2.x) / 2, (p1.y + p2.y) / 2, (p1.z + p2.z) / 2);
			cache[key]=index;

			return index;
		}


		private function h_enterFrame(evt:Event):void {
			count = (count + 1) % 200;
			if (count%50==0) {
				createIcosphere(Math.floor(count / 50));
			}
			xRot-=canvas.mouseY/50;
			yRot-=canvas.mouseX/50;
			render();
		}

		private function render():void {
			var g:Graphics=canvas.graphics;
			g.clear();
			g.lineStyle(1,0xffffff);
			for (var i:uint = 0; i < faces.length; i ++) {
				g.beginFill(0xffffff, 0.2);
				for (var j:uint = 0; j < faces[i].length; j ++) {
					var p:Point=v3dToP2d(vertexes[faces[i][j]]);
					if (j==0) {
						g.moveTo(p.x, p.y);
					} else {
						g.lineTo(p.x, p.y);
					}
				}
				g.endFill();
			}
		}

		private function v3dToP2d(v:Vector3D):Point {
			v=v.clone();
			var _x:Number,_y:Number,_z:Number;
			_y=v.y*Math.cos(xRot/180*Math.PI)-v.z*Math.sin(xRot/180*Math.PI);
			_z=v.y*Math.sin(xRot/180*Math.PI)+v.z*Math.cos(xRot/180*Math.PI);
			_x=v.x*Math.cos(yRot/180*Math.PI)-_z*Math.sin(yRot/180*Math.PI);
			_z=v.x*Math.sin(yRot/180*Math.PI)+_z*Math.cos(yRot/180*Math.PI);

			var scale:Number = fl / (fl + _z - viewPointZ) * zoom;
			return new Point(_x * scale, _y * scale);
		}
	}
}