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

Gumoski-Mira orbits

click to launch particle,
shift-click to change parameters
for more info on Gumoski-Mira maps, see
http://www.artegens.net/on/cic/GA2009Papers/p29.pdf
// click to launch particle,
// shift-click to change parameters
// for more info on Gumoski-Mira maps, see
// http://www.artegens.net/on/cic/GA2009Papers/p29.pdf
package  {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	[SWF(width=465,height=465)]
	public class GumoskiMiraOrbits extends Sprite {
		public var A:Number;
		public var B:Number;
		public function F (x:Number):Number {
			return A * x + 2 * (1 - A) * x * x / (1 + x * x);
		}

		public var b:Bitmap;
		public var bd:BitmapData;
		public var ct:ColorTransform;
		public var xy:Vector.<Point>;
		public var splines:Vector.<Spline2D>;
		public function GumoskiMiraOrbits () {
			A = 2 * Math.random () - 1;
			B = 2 * Math.random () - 1;

			bd = new BitmapData (465, 465, false, 0);
			addChild (b = new Bitmap (bd));
			ct = new ColorTransform (1, 1, 1, 1, -30, -20, -10);
			xy = new Vector.<Point> (3);
			splines = new Vector.<Spline2D> (xy.length);
			for (var i:int = 0; i < xy.length; i++) {
				xy [i] = new Point (
					10 * Math.random () - 5.0,
					10 * Math.random () - 5.0
				);
				splines [i] = new Spline2D (xy [i]);
				
			}
			stage.addEventListener (Event.ENTER_FRAME, draw);
			stage.addEventListener (MouseEvent.CLICK, click);
		}
		public function draw (e:Event):void {
			graphics.clear (); graphics.lineStyle (0, 0xffffff);
			for (var i:int = 0; i < xy.length; i++) {
				var z:Point = xy [i];
				var aa:Number = z.x * z.x;
				var bb:Number = z.y * z.y;
				if (aa + bb < 25) {
					var xi:Number = B * z.y + F (z.x);
					var yi:Number = -z.x + F (z.y);
					if ((z.x - xi)*(z.x - xi) + (z.y - yi)*(z.y - yi) > 1e-3) {
						z.x = xi; z.y = yi; splines [i].addNextPoint (z, graphics);
					} else {
						xy.splice (i, 1);
						splines.splice (i, 1);
						i--;
					}
				} else {
					xy.splice (i, 1);
					splines.splice (i, 1);
					i--;
				}
			}
			b.visible = false; bd.draw (this); b.visible = true;
			bd.colorTransform (bd.rect, ct);
		}
		public function click (e:MouseEvent):void {
			if (e.shiftKey) {
				A = 2 * mouseX / 465 - 1.0;
				B = 2 * mouseY / 465 - 1.0;
			} else {
				xy.push (new Point (
					10 * mouseX / 465 - 5.0,
					10 * mouseY / 465 - 5.0
				));
				splines.push (new Spline2D (xy [xy.length - 1]));
			}
		}
	}
}

import flash.display.Graphics;
import flash.geom.Point;
class Spline2D {
	public var points:Vector.<Point>
	public function Spline2D (p:Point) {
		points = new Vector.<Point>;
		for (var i:int = 0; i < 4; i++) points.push (p.clone ());
	}
	public function addNextPoint (p:Point, g:Graphics):void {
		points.shift (); points.push (p.clone ());
		// draw previous segment
		g.moveTo (465 * (5 + points [1].x) / 10, 465 * (5 + points [1].y) / 10);
		for (var i:int = 1; i < 11; i++) {
			p = spline (points [0], points [1], points [2], points [3], 0.1 * i);
			g.lineTo (465 * (5 + p.x) / 10, 465 * (5 + p.y) / 10);
		}
	}
	/* 
	* Calculates 2D cubic Catmull-Rom spline.
	* @see http://www.mvps.org/directx/articles/catmull/ 
	*/ 
	private function spline (p0:Point, p1:Point, p2:Point, p3:Point, t:Number):Point {
		return new Point (
			0.5 * ((          2*p1.x) +
				t * (( -p0.x           +p2.x) +
				t * ((2*p0.x -5*p1.x +4*p2.x -p3.x) +
				t * (  -p0.x +3*p1.x -3*p2.x +p3.x)))),
			0.5 * ((          2*p1.y) +
				t * (( -p0.y           +p2.y) +
				t * ((2*p0.y -5*p1.y +4*p2.y -p3.y) +
				t * (  -p0.y +3*p1.y -3*p2.y +p3.y))))
		);
	}
}