Latest snippets

Slow Circle Drawing

var canvas:BitmapData = new BitmapData(400,400,false, 0xCCCCCC);
addChild(new Bitmap(canvas));

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.fillRect(canvas.rect, 0xCCCCCC);
	
	var r:Number = Math.abs(200 - mouseX);
	var r2:Number = r * r;
	var inc:Number = 1 / r;
	var xp:Number = .00000001;
	var yp:Number = -r;
	while(yp<r){
		  var y:Number = 200 + yp;
		  yp += xp * inc;
		  xp = Math.sqrt(r2 - yp * yp);
		  canvas.setPixel(200 + xp, y, 0x000000);
		  canvas.setPixel(200 - xp, y, 0x000000);
	 }
}

A slow way to draw circles using setPixel().

var canvas:BitmapData = new BitmapData(400,400,false, 0xCCCCCC);
addChild(new Bitmap(canvas));

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.fillRect(canvas.rect, 0xCCCCCC);
	var r:Number = Math.abs(200 - mouseX);
	var r2:Number = r * r;
	var inc:Number = 1 / r;
	var xp:Number = .000001;
	var yp:Number = -r;
	while(yp <= 0){;
	     var x1:Number = 200 + xp;
		 var y1:Number = 200 + yp
		 var x2:Number = 200 - xp;
		 var y2:Number = 200 - yp;
		 canvas.setPixel(x1, y1, 0x000000);
		 canvas.setPixel(x1, y2, 0x000000);
		 canvas.setPixel(x2, y1, 0x000000);
		 canvas.setPixel(x2, y2, 0x000000);
		  yp += xp * inc;
		  xp = Math.sqrt(r2 - yp * yp);
	 }
}

Little better, still slow.

I was brainstorming about a few things today and somehow these two slow circle drawing algorithms popped out. These are pretty useless compared to some of the famous algorithms I’ve posted in the past. Kind of interesting nevertheless.

Function Chaining & Classes

package {
    import flash.display.Sprite;
	public class Chaining extends Sprite{
		public function Chaining(){
			  print(n(100).divide(2).plus(2));
			  // outputs 52              
			  print(n(100).plus(n(10).multiply(2)));
			  // outputs 120
		}
	}
}

function print(n:Num):void{
   trace(n.getValue());
}
function n(n:Number):Num{
   return new Num(n);
}

class Num{
	private var value:Number;
	
	public function Num(n:Number):void{
       value = n;
	}
	private function convert(n:*):Number{
		if (n is Num) n = n.getValue();
		return n;
	}
	public function getValue():Number{
		return value;
	}
	public function plus(n:*):Num{
		n = convert(n);
		value += n;
		return this;
	}
	public function minus(n:*):Num{
		n = convert(n);
		value -= n;
		return this;
	}
	public function multiply(n:*):Num{
		n = convert(n);
		value *= n;
		return this;
	}
	public function divide(n:*):Num{
		n = convert(n);
		value /= n;
		return this;
	}
}

This snippet is meant to be run as a document class. It shows how one might go about designing a class to make extensive use of function chaining.

Save BitmapData to your HD

import com.adobe.images.JPGEncoder;

var jpgEncoder:JPGEncoder = new JPGEncoder(80);
var file:FileReference = new FileReference();
var id:int = 0;

var bit:BitmapData = new BitmapData(400, 400, false, 0x000000);
addChild(new Bitmap(bit));

stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(evt:MouseEvent):void{
	// draw some perlin noise
	bit.perlinNoise(200,200, 2, Math.random()*100, true, false,0, true);
	//bit.draw(someClip);
	//bit.draw(someVideo);
	id++;
	file.save(jpgEncoder.encode(bit), "image_" +id+".jpg");
}

This snippet uses the as3corelib which you can download on this page. It uses the JPGEncoder class to save a jpeg image to a users HD. It also makes use of the flash player 10 FileReference.save() method.

I used BitmapData.perlinNoise() to quickly create an arbitrary image…. as the code comments suggest you could easily snapshot a video or other DisplayObject.

Closed Catmull-Rom

var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
addChild(new Bitmap(canvas));

var pnts:Array = new Array();
// make control points
for (var i:int = 0; i<5; i++){
	var t:Number = i * 72 * Math.PI /180;
	pnts.push(dot(200 + 100 * Math.cos(t),200 +100 * Math.sin(t)));   
}

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	canvas.fillRect(canvas.rect, 0x000000);
	curve(pnts);
	canvas.unlock();
}

function tangent(pk1:Sprite, pk_1:Sprite){
	return new Point((pk1.x - pk_1.x) / 2, (pk1.y - pk_1.y) / 2);
}

// all math from http://en.wikipedia.org/wiki/Cubic_Hermite_spline
function curve(p:Array, res:Number=.03):void{
	var px:Number = 0;
    var py:Number = 0;
	var pIter:int = p.length - 1;
	var m:Array = [];
	
	m[0] = tangent(p[1] ,  p[pIter]);
	for (var i:int = 1; i<pIter; i++){
		m[i] = tangent(p[i + 1], p[i - 1]);
	}
	m[pIter] = tangent(p[0],p[pIter-1]);
	
	for (var t:Number = 0; t < 1; t+=res){
		 var t_2:Number = t * t;
		 var _1_t:Number = 1 - t;
		 var _2t:Number = 2 * t;
		 
		 var h00:Number =  (1 + _2t) * (_1_t) * (_1_t);
		 var h10:Number =  t  * (_1_t) * (_1_t);
		 var h01:Number =  t_2 * (3 - _2t);
		 var h11:Number =  t_2 * (t - 1);
		 
		 for (var k:int = 0; k < pIter; k++){
			 var k1:int = k + 1;
			 var pk:Sprite = p[k];
			 var pk1:Sprite = p[k1];
			 var mk:Point = m[k];
			 var mk1:Point = m[k1];
			 px = h00 * pk.x + h10 * mk.x + h01 * pk1.x + h11 * mk1.x;
			 py = h00 * pk.y + h10 * mk.y + h01 * pk1.y + h11 * mk1.y;
			 canvas.setPixel(px, py, 0xFFFFFF);
		 }
		  pk = p[k];
		  pk1 = p[0];
		  mk = m[k];
		  mk1= m[0];
		 
		  px = h00 * pk.x + h10 * mk.x + h01 * pk1.x + h11 * mk1.x;
		  py = h00 * pk.y + h10 * mk.y + h01 * pk1.y + h11 * mk1.y;
		  canvas.setPixel(px, py, 0xFFFFFF);
	}
}

// draggable dot
function dot(xp:Number, yp:Number, col:uint = 0xFF0000, rad:Number=4):Sprite {
	var s:Sprite = Sprite(addChild(new Sprite));
	s.x = xp;
	s.y = yp;
	with(s.graphics) beginFill(col), drawCircle(0,0,rad);
	s.buttonMode = true;
	s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
	return s;
}
function onDrag(evt:MouseEvent):void {
	evt.currentTarget.startDrag()
}
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
function onUp(evt:MouseEvent):void{
	stopDrag();
}

This a variation on a post from a few days ago. This shows how to create a closed Catmull Rom spline.

See the other Catmull-Rom related Posts

Hippopede

x=stage.stageWidth/2;
y=stage.stageHeight/2;
var xp:Number = 0, yp:Number = 0;
var r:Number = 0, t:Number = 0;
var speed:Number=.1;

var range:Number=.2;
var b:Number = 20;
var a:Number = b * range;
var orbit:Number = 2 * Math.PI + speed;
 
graphics.lineStyle(0,0x000000);

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	var sin:Number=Math.sin(t);
	r =  Math.sqrt(4 * b * (a - b * (sin * sin)));
	xp= r * Math.cos(t);
	yp= r * sin;
	
    if (t==0) {
		graphics.moveTo(xp, yp);
	} else {
		graphics.lineTo(xp, yp);
	}

	t += speed;
	
	if (t > orbit) {
		range += .5;
		a= b * range;
		t= 0;
	}
}

The above draws a Hippopede

Fermat’s Spiral

x = stage.stageWidth / 2;
y = stage.stageHeight / 2;

var xp:Number = 0, yp:Number = 0;
var r:Number = 0, t:Number = 0;
var speed:Number = .07;
var scale:Number = 20;

var plot0:Shape = Shape(addChild(new Shape()));
var plot1:Shape = Shape(addChild(new Shape()));
plot0.graphics.lineStyle(0,0x000000);
plot1.graphics.lineStyle(0,0x000000);

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	 r =  scale * Math.sqrt(t);
	 xp =  r * Math.cos(t);
	 yp =  r * Math.sin(t);
	 t += speed;
	 
	plot0.graphics.lineTo(xp, yp);
    plot1.graphics.lineTo(-xp, -yp);
}

This snippet draws Fermat’s Spiral.

var obj:Object = new Function()

var Pnt:Function = function(xp:Number, yp:Number){
	
	var x:Number = xp;
	var y:Number = yp
	
	this.setX = function(v:int):void{
		x = v;
	}
	this.setY = function(v:int):void{
		y = v;
	}
	this.getX = function():int {
		return x;
	}
	this.getY = function():int {
		return y;
	}
}

var p:Object = new Pnt(10,10);

trace(p.getX(), p.getY());
p.setX(100);
trace(p.getX());

/*
outputs:
10, 10
100
*/

Another way to define and instantiate Objects on the timeline. Interesting, but I don’t recommend it over actual classes…

Interesting Function Composition

var multBy2Add3:Function = add(3, mult(2));

trace(multBy2Add3(10));
// 10 * 2  = 20
//  20 + 3 = 23

var add2AndSquare = sq(add(2));

trace(add2AndSquare(8));
// 8 + 2 = 10
// 10 * 10 = 100

var multBy2_3times:Function = repeat(3,mult(2));

trace(multBy2_3times(3));
// 3 * 2 = 6;
// 6 * 2 = 12;
// 12 * 2 = 24

// you can also chain for even less readability
trace(sq(mult(5,add(1)))(4));
// 4 + 1 = 5
// 5 * 5 = 25;
// 25 * 25 = 625;

/*
outputs: 
12
100
24
625
*/

// function  composition
const F:Function = function(a:*):*{return a};
function mult(scalar:Number, f:Function=null):Function{
	if (f == null) f = F;
	 return function(n:Number){
		return f(n) * scalar;
	}
}

function add(off:Number, f:Function=null):Function{
	 if (f == null) f = F;
	 return function(n:Number){
		return f(n) + off;
	}
}
function sq(f:Function=null):Function{
	 if (f == null) f = F;
	 return function(n:Number){
		 var v:Number = f(n);
		return  v * v;
	}
}
function repeat(times:int, f:Function):Function {
	 if (f == null) f = F;
	 return function (n:Number){
		 var v:Number = n;
		 for (var i:int = 0; i<times; i++) v = f(v);
		 return v;
	 }
}

The above shows some interesting function composition… this demo contains the following functions:

mult();
add();
sq();
repeat();

These functions are designed to be combined to create new functions.

k-th Order Catmull-Rom Spline

var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
addChild(new Bitmap(canvas));
var pnts:Array = new Array();
// make 8 control points
for (var i:int = 0; i<8; i++){
	pnts.push(dot(50 + i * (30 + Math.random()*10),
							 50 + i * (30 + Math.random()*10)));
}
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	canvas.fillRect(canvas.rect, 0x000000);
	curve(pnts);
	canvas.unlock();
}
function tangent(pk1:Sprite, pk_1:Sprite){
	return new Point((pk1.x - pk_1.x) / 2, (pk1.y - pk_1.y) / 2);
}
// all math from http://en.wikipedia.org/wiki/Cubic_Hermite_spline
function curve(p:Array, res:Number=.03):void{
	var px:Number = 0;
	var py:Number = 0;
	var pIter:int = p.length - 1;
	var m:Array = [];
	m[0] = tangent(p[1], p[0]);
	for (var i:int = 1; i<pIter; i++){
		m[i] = tangent(p[i + 1], p[i - 1]);
	}
	m[pIter] = tangent(p[pIter], p[pIter - 1]);
	for (var t:Number = 0; t <1; t+=res){
		 var t_2:Number = t * t;
		 var _1_t:Number = 1 - t;
		 var _2t:Number = 2 * t;
		 var h00:Number =  (1 + _2t) * (_1_t) * (_1_t);
		 var h10:Number =  t  * (_1_t) * (_1_t);
		 var h01:Number =  t_2 * (3 - _2t);
		 var h11:Number =  t_2 * (t - 1);
		 for (var k:int = 0; k <pIter; k++){
			 var k1:int = k + 1;
			 var pk:Sprite = p[k];
			 var pk1:Sprite = p[k1];
			 var mk:Point = m[k];
			 var mk1:Point = m[k1];
			 px = h00 * pk.x + h10 * mk.x + h01 * pk1.x + h11 * mk1.x;
			 py = h00 * pk.y + h10 * mk.y + h01 * pk1.y + h11 * mk1.y;
			 canvas.setPixel(px, py, 0xFFFFFF);
		 }
	}
}
// draggable dot
function dot(xp:Number, yp:Number, col:uint = 0xFF0000, rad:Number=4):Sprite {
	var s:Sprite = Sprite(addChild(new Sprite));
	s.x = xp;
	s.y = yp;
	with(s.graphics) beginFill(col), drawCircle(0,0,rad);
	s.buttonMode = true;
	s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
	return s;
}
function onDrag(evt:MouseEvent):void {
	evt.currentTarget.startDrag()
}
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
function onUp(evt:MouseEvent):void{
	stopDrag();
}

More Catmull-Rom stuff. This one can have any number of control points:


Check it out here: