Browse the notebook

Category: Graphics

Color Breeder (aka Features)

Choose two colors to breed them and create 5 new colors:

This is a speed coded pen from awhile back – the features object is interesting – it allows two objects to be bred together. In this case two colors. I could see this is as part of some advanced/abstract colorpicker that allows the user to home in on a color.

Read snippet: Color Breeder (aka Features)

3d Point to 2d Point (Easy Mini 3d Engine)

Many years ago when I had just started programming I found this absolute gem by Andries Odendaal.

modern es6 version

let rotX = 0, rotY = 0,
    perspective = 500, 
    depth,
    currX, currY;
// learned something like this at Andries Odendaal's www.wireframe.co.za 
function point3d(x, y, z) {
    let cosX = Math.cos(rotX),
        cosY = Math.cos(rotY),
        sinX = Math.sin(rotX),
        sinY = Math.sin(rotY),
        posX, posY, posZ;
   
    posZ = z * cosX - x * sinX,
    posX = z * sinX + x * cosX,
    posY = y * cosY - posZ * sinY,
    posZ = y * sinY + posZ * cosY;
    
    depth = 1 / (posZ / perspective + 1);
    currX = posX * depth;
    currY = posY * depth;
 
    return [ currX, currY, depth ];
}

Here’s is an example of it in action:

I’ve used this code many many times, it’s just easy to throw into any language and instantly get 3d points rendered in 2d. Here is a short video of a Java applet from 2003 called “Catch Env” that made use of it:

Here is the source code for that ^^
http://www.zevanrosser.com/shape2/j/Catchenv.java

You’ll notice in that source, that I nested the equation to allow for local and global transformations. It was around that time that I learned the ins and outs of real 2D and 3D matrix transformation math… Ken Perlin’s classfiles from NYU were a real help when I was learning that stuff. I don’t think this was the exact file I was working with, but it was definitely on his site somewhere.

Before all that, during my junior year in college I created a 3d engine based off Odendaal’s code in Director (Lingo). Here is a video of some of the demos for it:

…and here is a strange screenshot from my personal website at the time:

Just an example of a powerful snippet and a gateway to learning matrix transformation math. When I first really dug in to html5 canvas – before WebGL was supported so widely – having this trick up my sleeve was great. As you can see in the below link, I used it more than a few times back then:

Daily canvas experiments:

http://zreference.com/projects/all-graphics.php

😀

Read snippet: 3d Point to 2d Point (Easy Mini 3d Engine)

Hermit Crab Curve as PRNG (a deterministic pseudo-random number generator with contrast and smoothness – inspired by stochastic and organic randomness)

Around 2015 I had the idea for a PRNG that would clamp itself and have moments of “smoothness”. When I got around to trying to create such a thing, the result was something I jokingly called the “Hermit Crab Curve”. I also called it the “Shard Curve”.

The equation for the curve defines a radius in polar coordinates:

Where a and d are paramters that control the detail of the curve. o is a rotation and offset value for the angle and s is a scalar. Note the use of rem. The resulting curve is much less interesting if a standard modulo is used in place of a remainder:

The above variable values were found using this interactive version of the equation:

To illustrate how you might use this as a PRNG I created this fork of the above pen:

That, in combination with the information from my other article from yesterday… Should be enough to see what I mean.


You can read the original description of the Hermit Crab Curve that I created using ArcType here:

http://zevanrosser.com/arctype-dev/hermit-crab-curve.html

If you end up using this for something interesting let me know. I’d love to see it 😀

Read snippet: Hermit Crab Curve as PRNG (a deterministic pseudo-random number generator with contrast and smoothness – inspired by stochastic and organic randomness)

Gumowski/Mira Pseudo-Soundwave

[SWF(width = 600, height = 600)]
var a:Number = 0.02;
var b:Number = .9998;
 
var xn1:Number = 5;
var yn1:Number = 0;
var xn:Number, yn:Number;
 
var scale:Number = 10;
var iterations:Number = 20000;
var step:Number = stage.stageWidth / iterations;

function f(x:Number):Number{
    var x2:Number = x * x;
    return a * x + (2 * (1 - a) * x2) / (1 + x2);
}

var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(600,600,false,0xEFEFEF)))).bitmapData;

var circle = new Sprite();
with(circle.graphics) beginFill(0, 0.3), drawCircle(2,2,1);

var dot:BitmapData = new BitmapData(4,4,true, 0x00000000);
dot.draw(circle);

var pnt:Point = new Point();

var txt:TextField = TextField(addChild(new TextField()));
txt.text = "move mouse";
                                                      
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
   
    canvas.fillRect(canvas.rect, 0xEFEFEF);

    a = mouseY / 1000;
    xn1 = mouseX / 30;
    yn1 = 0;
    for (var i:int = 0; i<iterations; i++){
          xn = xn1;
          yn = yn1;
         
          xn1 = b * yn + f(xn);
          yn1 =  -xn + f(xn1);
		  pnt.x = i * step;
		  pnt.y = 300 + yn1 * scale;
		  canvas.copyPixels(dot, dot.rect, pnt, null, null, true);
		
    }
}

Try it out:

Gumowski Mira Pseudo-soundwave – wonderfl build flash online

Read snippet: Gumowski/Mira Pseudo-Soundwave

Circle Fitting

var circs:Array = []
var circNum:int = 600;
addEventListener(Event.ENTER_FRAME, onAdd);
function onAdd(evt:Event):void {
	if (circs.length < circNum){
		makeGrowable();
	}
}

function makeGrowable(){
	
	var s:MovieClip = MovieClip(addChild(new MovieClip()));
	s.x = Math.random() * stage.stageWidth;
	s.y = Math.random() * stage.stageHeight;
	with(s.graphics){
		lineStyle(0,0);
		drawCircle(0,0,10);
	}
	s.scaleX = s.scaleY = 0;
	circs.push(s);
	s.addEventListener(Event.ENTER_FRAME, onScaleUp);
}

function onScaleUp(evt:Event):void {
	var c:MovieClip = MovieClip(evt.currentTarget);
	c.scaleX = c.scaleY += 0.05;
	for (var i:int = 0; i<circs.length; i++){
		var circ:MovieClip = circs[i];
		if (circ != c){
			var amt:Number = circ.width/2 + c.width/2;
			var dx:Number = circ.x - c.x;
			var dy:Number = circ.y - c.y;
			var dist:Number = Math.sqrt(dx * dx + dy * dy);
			if (amt > dist){
				c.removeEventListener(Event.ENTER_FRAME, onScaleUp);
				if (c.scaleX < 0.1){
					if (contains(c)){
					removeChild(c);
					}
				}
			}
		}
		
	}
}

Circle fitting is one of those things I’ve never bothered to do… today I figured I’d give it a try and this is what I came up with. I posted it on wonderfl:

CircleFitting – wonderfl build flash online
Read snippet: Circle Fitting

3D Ring

[SWF(width = 500, height=500)]
var ring:MovieClip = createRing();
ring.x = stage.stageWidth / 2;
ring.y = stage.stageHeight / 2;
addChild(ring);

function createRing(sectionNum:int = 30):MovieClip{
	var container:MovieClip = new MovieClip();
	container.circles = [];
	container.theta = 0;
	container.thetaDest = 0;
	var step:Number = (Math.PI * 2) / sectionNum;
	for (var i:int = 0; i<sectionNum; i++){
		var c:MovieClip = new MovieClip();
		with (c.graphics){
			lineStyle(0,0x000000);
			beginFill(0xCCCCCC);
			drawCircle(0,0,20);
		}
		c.thetaOffset = step * i;
		container.addChild(c);
		container.circles.push(c);
	}
	container.addEventListener(Event.ENTER_FRAME, onRun);
	return container;
}
function onRun(evt:Event):void {
	var container:MovieClip = MovieClip(evt.currentTarget);
	var num:int = container.circles.length;
	for (var i:int = 0; i<num; i++){
		var c:MovieClip = container.circles[i];
		var angle:Number = container.theta + c.thetaOffset;
		c.x = 200 * Math.cos(angle);
		c.y = 100 * Math.sin(angle);
		c.scaleX = (100 + c.y) / 120 + 0.2;
		c.scaleY = c.scaleX;
	}
	container.circles.sortOn("y", Array.NUMERIC);
	for (i = 0; i<num; i++){
		container.addChild(container.circles[i]);
	}
	if (container.mouseX < -100){
		container.thetaDest -= 0.05;
	}
	if (container.mouseX > 100){
		container.thetaDest += 0.05;
	}
	container.theta += (container.thetaDest  - container.theta) / 12;
	
}

This snippet shows how to create a 3D ring navigation using sine and cosine. Have a look:

Ring – wonderfl build flash online
Read snippet: 3D Ring

Circle Mouse Toy

var circles:Array = [];
for (var i:int = 0; i<30; i++){
	var c:Sprite = makeCircle();
	c.x = stage.stageWidth / 2;
	c.y = stage.stageHeight / 2;
	c.scaleX = 1 + i/2;
	c.scaleY = 0.5 + i/4;
	addChild(c);
	circles.push(c);
}
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	circles[0].y += (mouseY - circles[0].y) / 4;
	for (var i:int = 1; i<circles.length; i++){
		var pre:Sprite = circles[i - 1];
		circles[i].y += (pre.y - circles[i].y) / 4;
	}
}
function makeCircle():Sprite{
	var s:Sprite = new Sprite();
	with(s.graphics){
		lineStyle(0,0x000000);
		drawCircle(0,0,10);
	}
	return s;
}

This morning I woke up with a vision of this simple mouse toy in my head. I decided I might as well code it up… I may do more simple things like this in the next few days, it’s relaxing.

Mouse Toy – wonderfl build flash online
Read snippet: Circle Mouse Toy

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.

Read snippet: Recursion Form

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).

Read snippet: Logistic Map Play

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

Read snippet: Connect The Dots E8