Latest snippets

Recursion Form

x = y = 10
graphics.lineStyle(1,0);
drawBox(6);

function drawBox(iter:Number=10, count:Number=1, y:Number=0, w:Number=500):void{
       if (count < iter){
               var width:Number = w / count
               for (var i:int = 0; i<count; i++){
                   graphics.drawRect(i * width, width * count/w, width, width);
               }
               count++;
               drawBox(iter, count, y, width);
       }
}

This small snippet just draws this image:

If you have an idea for a short recursive snippet. Feel free to post it in the comments.

To release or not to release…

So I have a QuickBox2D editor that I’ve had since the earliest version of QuickBox2D. It is really pretty buggy and imperfect. I’m wondering if I should release it even though it’s really buggy… my main issue is I won’t be able to guarantee that it is a safe editor to use for real projects.

Thoughts? Should I release it anyway?

Logistic Map Play

var offX:Number = 100;
var offY:Number = 300;
var scalarX:Number = 6;
var scalarY:Number = 200;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void{
	var r:Number = mouseY / 100;
	var xn:Number = (mouseX - 100) / 650;
	var xn1:Number = 0;
	graphics.clear();
	graphics.lineStyle(0,0);
	for (var i:int = 0; i<100; i++){
	  xn1 = r * xn * (1 - xn);
	  xn = xn1;
	  if (i == 0){
		graphics.moveTo(offX+i*scalarX,offY+xn1*scalarY);  
	  }else{
		graphics.lineTo(offX+i*scalarX, offY+xn1*scalarY);
	  }
	}
}

Whenever I can’t decide what kind of snippet to make, I simply go to wikipedia or mathworld for a bit and I always end up with something. I’ve messed with Logistic Maps before (when learning about strange attractors). This is a simple rendering where the x and y axis change the biotic potential (r) and the starting value for x.

Here is the link I used for reference.


Have a look at the swf (just move your mouse around).

QuickBox2D Nodes

Been thinking about nonsense nodes recently so I created this with my QuickBox2D editor. I have yet to release the editor because its buggy, but it does work nicely for some things:


Have a look at the swf….


import com.actionsnippet.qbox.*;

stage.quality="medium";
var sim:QuickBox2D = new QuickBox2D(this, {gravityY:0.2});

sim.setDefault({fillColor:0xEFEFEF, fillAlpha:0.5, lineColor:0x666666});


var auto4:QuickObject = sim.addBox({x:9.33, y:4.67, width:1.33, height:1.33, angle: 0, density:1});
var auto5:QuickObject = sim.addBox({x:11, y:4.67, width:1.33, height:1.33, angle: 0, density:1});
var auto6:QuickObject = sim.addBox({x:12.67, y:4.67, width:1.33, height:1.33, angle: 0, density:1});
var auto7:QuickObject = sim.addCircle({x:11, y:3, radius:0.67, density:1});
var auto11:QuickObject = sim.addBox({x:9, y:6, width:0.67, height:0.67, angle: 0, density:1});
var auto13:QuickObject = sim.addBox({x:9, y:7, width:0.67, height:0.67, angle: 0, density:1});
var auto15:QuickObject = sim.addBox({x:11, y:6.33, width:1.33, height:1.33, angle: 0, density:1});
var auto17:QuickObject = sim.addBox({x:14, y:4.33, width:0.67, height:0.67, angle: 0, density:1});
var auto18:QuickObject = sim.addBox({x:15, y:4.33, width:0.67, height:0.67, angle: 0, density:1});
var auto19:QuickObject = sim.addBox({x:14, y:3, width:0.67, height:0.67, angle: 0, density:1});
var auto25:QuickObject = sim.addBox({x:12.17, y:6.33, width:0.33, height:1.33, angle: 0, density:1});
var auto26:QuickObject = sim.addBox({x:13.17, y:6.33, width:0.33, height:1.33, angle: 0, density:1});
var auto29:QuickObject = sim.addBox({x:13.67, y:7.67, width:3.33, height:0.67, angle: 0, density:1});
var auto32:QuickObject = sim.addBox({x:10.67, y:7.67, width:0.67, height:0.67, angle: 0, density:1});
var auto35:QuickObject = sim.addBox({x:9, y:8, width:0.67, height:0.67, angle: 0, density:1});
var auto37:QuickObject = sim.addBox({x:9, y:9, width:0.67, height:0.67, angle: 0, density:1});
var auto38:QuickObject = sim.addBox({x:10.33, y:9.33, width:1.33, height:1.33, angle: 0, density:1});
var auto39:QuickObject = sim.addBox({x:11.67, y:9, width:0.67, height:0.67, angle: 0, density:1});
var auto40:QuickObject = sim.addBox({x:12.67, y:9.67, width:0.67, height:0.67, angle: 0, density:1});
var auto41:QuickObject = sim.addBox({x:13.67, y:9.67, width:0.67, height:0.67, angle: 0, density:1});
var auto42:QuickObject = sim.addBox({x:15, y:9.33, width:1.33, height:1.33, angle: 0, density:1});
var auto43:QuickObject = sim.addBox({x:11.67, y:10, width:0.67, height:0.67, angle: 0, density:1});
var auto44:QuickObject = sim.addBox({x:11.67, y:11, width:0.67, height:0.67, angle: 0, density:1});
var auto45:QuickObject = sim.addBox({x:15, y:10.67, width:1.33, height:0.67, angle: 0, density:1});
var auto46:QuickObject = sim.addBox({x:9, y:10, width:0.67, height:0.67, angle: 0, density:1});
var auto62:QuickObject = sim.addCircle({x:12.67, y:1, radius:0.33, density:0});
// joints:
sim.setDefault({frequencyHz:0.7, lineColor:0x666666});
var auto8:QuickObject = sim.addJoint({a:auto7.body, b:auto4.body, x1:11, y1:3, x2:9.33, y2:4.33});
var auto9:QuickObject = sim.addJoint({a:auto7.body, b:auto5.body, x1:11, y1:3, x2:11, y2:4.33});
var auto10:QuickObject = sim.addJoint({a:auto7.body, b:auto6.body, x1:11, y1:3, x2:12.67, y2:4.33});
var auto12:QuickObject = sim.addJoint({a:auto11.body, b:auto4.body, x1:9, y1:6, x2:9, y2:5});
var auto14:QuickObject = sim.addJoint({a:auto11.body, b:auto13.body, x1:9, y1:6, x2:9, y2:7});
var auto16:QuickObject = sim.addJoint({a:auto5.body, b:auto15.body, x1:11, y1:5, x2:11, y2:6});
var auto20:QuickObject = sim.addJoint({a:auto6.body, b:auto19.body, x1:12.67, y1:4.33, x2:14, y2:3});
var auto21:QuickObject = sim.addJoint({a:auto19.body, b:auto17.body, x1:14, y1:3, x2:14, y2:4.33});
var auto22:QuickObject = sim.addJoint({a:auto17.body, b:auto18.body, x1:14, y1:4.33, x2:15, y2:4.33});
var auto23:QuickObject = sim.addJoint({a:auto17.body, b:auto6.body, x1:14, y1:4.33, x2:13, y2:4.33});
var auto24:QuickObject = sim.addJoint({a:auto7.body, b:auto19.body, x1:11, y1:3, x2:14, y2:3});
var auto27:QuickObject = sim.addJoint({a:auto6.body, b:auto25.body, x1:12.17, y1:5.1, x2:12.17, y2:5.97});
var auto28:QuickObject = sim.addJoint({a:auto6.body, b:auto26.body, x1:13.2, y1:5.1, x2:13.23, y2:6.1});
var auto30:QuickObject = sim.addJoint({a:auto18.body, b:auto29.body, x1:15, y1:4.33, x2:15, y2:7.67});
var auto31:QuickObject = sim.addJoint({a:auto17.body, b:auto29.body, x1:14, y1:4.33, x2:15, y2:7.67});
var auto33:QuickObject = sim.addJoint({a:auto15.body, b:auto32.body, x1:11, y1:6.33, x2:10.67, y2:7.67});
var auto34:QuickObject = sim.addJoint({a:auto32.body, b:auto29.body, x1:10.67, y1:7.67, x2:12.33, y2:7.67});
var auto36:QuickObject = sim.addJoint({a:auto13.body, b:auto35.body, x1:9, y1:7, x2:9, y2:8});
var auto47:QuickObject = sim.addJoint({a:auto35.body, b:auto37.body, x1:9, y1:8, x2:9, y2:9});
var auto48:QuickObject = sim.addJoint({a:auto46.body, b:auto37.body, x1:9, y1:10, x2:9, y2:9});
var auto49:QuickObject = sim.addJoint({a:auto37.body, b:auto38.body, x1:9, y1:9, x2:10.33, y2:9.33});
var auto50:QuickObject = sim.addJoint({a:auto46.body, b:auto38.body, x1:9, y1:10, x2:10.33, y2:9.33});
var auto51:QuickObject = sim.addJoint({a:auto38.body, b:auto39.body, x1:10.33, y1:9.33, x2:11.67, y2:9});
var auto52:QuickObject = sim.addJoint({a:auto38.body, b:auto43.body, x1:10.33, y1:9.33, x2:11.67, y2:10});
var auto53:QuickObject = sim.addJoint({a:auto38.body, b:auto44.body, x1:10.33, y1:9.33, x2:11.67, y2:11});
var auto54:QuickObject = sim.addJoint({a:auto39.body, b:auto40.body, x1:11.67, y1:9, x2:12.67, y2:9.67});
var auto55:QuickObject = sim.addJoint({a:auto43.body, b:auto40.body, x1:11.67, y1:10, x2:12.67, y2:9.67});
var auto56:QuickObject = sim.addJoint({a:auto44.body, b:auto40.body, x1:11.67, y1:11, x2:12.67, y2:9.67});
var auto57:QuickObject = sim.addJoint({a:auto41.body, b:auto40.body, x1:13.67, y1:9.67, x2:12.67, y2:9.67});
var auto58:QuickObject = sim.addJoint({a:auto41.body, b:auto42.body, x1:13.67, y1:9.67, x2:14.67, y2:9.67});
var auto59:QuickObject = sim.addJoint({a:auto42.body, b:auto29.body, x1:14.67, y1:9, x2:15, y2:7.67});
var auto60:QuickObject = sim.addJoint({a:auto42.body, b:auto29.body, x1:15.33, y1:9, x2:15, y2:7.67});
var auto61:QuickObject = sim.addJoint({a:auto42.body, b:auto45.body, x1:15, y1:9.33, x2:15, y2:10.67});
var auto63:QuickObject = sim.addJoint({a:auto62.body, b:auto7.body, x1:12.67, y1:1, x2:11, y2:3});
var auto64:QuickObject = sim.addJoint({a:auto62.body, b:auto19.body, x1:12.67, y1:1, x2:14, y2:3});
var auto65:QuickObject = sim.addJoint({a:auto25.body, b:auto29.body, x1:12.17, y1:6.8, x2:12.27, y2:7.67});
var auto66:QuickObject = sim.addJoint({a:auto26.body, b:auto29.body, x1:13.2, y1:6.8, x2:13.2, y2:7.6});

sim.start();
sim.mouseDrag();

Catmull-Rom Error

I was messing with Catumull Rom spline code from awhile back and this this came out:

[SWF(width = 500, height= 500)]
var pnts:Array = new Array();
// make 8 control points
for (var i:int = 0; i<8; i++){
    pnts.push(dot(50 + Math.random() * 80 * i, Math.random()*(stage.stageHeight-40)+20));
}
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
    
    graphics.clear();
    graphics.lineStyle(0,0);
    curve(pnts); 
}
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=.05):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;
             if (k == 0){
				graphics.moveTo(px, py); 
			 }else{
				graphics.lineTo(px, py);
			 }
			 
            // 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);
stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
function onDown(evt:MouseEvent):void{
      dotsVisible(false);
}
function onUp(evt:MouseEvent):void{
    stopDrag();
    dotsVisible(true);
}

function dotsVisible(bool:Boolean):void{
	for (var i:int = 0; i<pnts.length; i++){
      pnts[i].visible = bool;
     }
}


You can see the swf over at wonderfl.

Connect The Dots E8

[SWF(width = 500, height = 500)]
const TWO_PI:Number = Math.PI * 2;
var centerX:Number = stage.stageWidth / 2;
var centerY:Number = stage.stageHeight / 2;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void{
	// data
	var points:Array = [];
	var i:int = 0;
	var pointNum : int = Math.max(2,int(mouseX / 12))
	
	var radius:Number = 200;
	var step:Number = TWO_PI / pointNum;
	var theta:Number = step / 2;
	for (i = 0; i<pointNum; i++){
		var xp:Number = centerX + radius * Math.cos(theta);
		var yp:Number = centerY + radius * Math.sin(theta);
		points[i] = new Point(xp, yp);
		theta += step;
	}
	// render
	graphics.clear();
	graphics.lineStyle(0,0);
	for ( i = 0; i<pointNum; i++){
     var a:Point = points[i];
     for (var j:int = 0; j<pointNum; j++){
        var b:Point = points[j];
        if (a != b){
		   graphics.drawCircle(a.x, a.y, 10);
		   graphics.moveTo(a.x, a.y);
	       graphics.lineTo(b.x, b.y);
        }
     }
   }
}

I’ve been using this geometric shape for lots of different things recently. Including during consulting gigs as a helpful visualization. Just move your mouse left and right… I particularly like the simpler forms you get by moving your mouse to the left (triangles squares and simple polygons):

Connect The Dots – wonderfl build flash online

While not entirely related this wikipedia article is interesting.

[EDIT : Thanks to martin for reminding me that I can do away with the if statement here in the above code ]

graphics.clear();
graphics.lineStyle(0,0);
for (i = 0; i<pointNum; i++) {
	var a:Point=points[i];
	for (var j:int = i+1; j<pointNum; j++) {
		var b:Point=points[j];
		graphics.drawCircle(a.x, a.y, 10);
		graphics.moveTo(a.x, a.y);
		graphics.lineTo(b.x, b.y);
	}
}
graphics.drawCircle(a.x, a.y, 10);

I implemented that change over at wonderfl and it works nicely

Nonsense Clocks

[SWF(width = 500, height=500, backgroundColor=0x000000)]

var clockNum:int = 100;
var clocks:Vector.<Function> = new Vector.<Function>(clockNum, true);

var clockContainer:Sprite = Sprite(addChild(new Sprite()));
clockContainer.x = stage.stageWidth / 2;
clockContainer.y = stage.stageHeight / 2;
buildClocks();
runClocks();

function buildClocks():void{
	for (var i:int = 0; i<clockNum; i++){
		var theta:Number = Math.random() * Math.PI * 2;
		var radius:Number = Math.random() * 200;
		var xp:Number = radius * Math.cos(theta);
		var yp:Number = radius * Math.sin(theta);
		clocks[i] = makeClock(xp,yp,Math.random() * Math.PI * 2);
	}
}
function runClocks():void{
	addEventListener(Event.ENTER_FRAME, onRunClocks);
}
function onRunClocks(evt:Event):void{
	for (var i:int = 0; i<clockNum; i++){
		clocks[i]();
	}
	clockContainer.rotationX = clockContainer.mouseY / 30;
	clockContainer.rotationY = -clockContainer.mouseX / 30;
}
function makeClock(x:Number, y:Number, time:Number=0):Function{
	var radius:Number = Math.random() * 20 + 5;
	var border:Number = radius * 0.2;
	var smallRadius:Number = radius - radius * 0.3;
	
	var clock:Sprite = Sprite(clockContainer.addChild(new Sprite()));
	clock.x = x;
	clock.y = y;
	clock.z = 100 - Math.random() * 200;
	clock.rotationX = Math.random() * 40 - 20;
	clock.rotationY = Math.random() * 40 - 20;
	clock.rotationZ = Math.random() * 360;
	return function():void{
		with (clock.graphics){
			clear(); 
			lineStyle(1,0xFFFFFF); 
			drawCircle(0,0,radius + border);
			var xp:Number = smallRadius * Math.cos(time/2);
			var yp:Number = smallRadius * Math.sin(time/2);
			moveTo(0,0);
			lineTo(xp, yp);
			xp = radius * Math.cos(time);
			yp = radius * Math.sin(time);
			moveTo(0,0);
			lineTo(xp, yp);
		}
		time+=0.1;
	}
}


You can go check the swf out at wonderfl.net…