Mandelbrot Matrix

 317 views  0 likes





Raw gif (gif) – Video (mp4) – Video (ogv) – Preview (png)
language: javascript

const pi = Math.PI;
const pi2 = pi * 2;
function point(x,y,size){
    x *= canvas.width;
    y *= canvas.height;
	// Draw it
    ctx.beginPath();
	// The last parameters are fromAngle and toAngle
	// (The function also allows making a part of a circle)
    ctx.arc(x, y, size, 0, pi2);
	// Draw our path
    ctx.fill();
}

class ComplexNumber{
    constructor(real, im){
    	this.r = real || 0.0;
        this.i = im || 0.0;
    }
    
    pow2(){
        let a = this.r;
        let b = this.i;
        this.r = a * a - b * b;
        this.i = 2 * (a * b);
    	return this;
    }
    
    len(){
    	return Math.sqrt(this.r * this.r + this.i * this.i);
    }
    
    times(k){
        this.r *= k;
        this.i *= k;
        return this;
    }
    
    add(complex){
        this.r += complex.r;
        this.i += complex.i;
        
    	return this;
    }
}

function randomLetter(){
	let letterCode = "a".charCodeAt(0);
    letterCode += Math.pow(Math.random() * 1e4, 2.0);
    let letter = String.fromCharCode(letterCode);
	return letter;
}

let s = 42;
let letters = [];

// Original version went from i=0 to i=s
// Bus look at next comment...
for(let i = 0; i < s/2; i++){
    letters.push([]);
    for(let j = 0; j < s; j++){
        letters[i].push(randomLetter());
    }
}
// Copy first vertical half of screen in second
// So gif loops in 21 frames instead of 42
// Note: I further reduced to 10 frames by
// moving 2 rows at the time
for(let i = s/2; i < s; i++){
    letters.push([]);
    for(let j = 0; j < s; j++){
        letters[i].push(letters[i-s/2][j]);
    }
}

function moveLetters(){
    // Move last row to top
    let lastRow = letters[letters.length - 1];
	letters.splice(0,0,lastRow);
    // Remove copy at the end
    letters.splice(letters.length-1,1)
}

function render(can, time){
    ctx = can.getContext("2d");
 
    // Clear screen
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0,0,can.width,can.height);
    
	// Choose color
    
    ctx.font =  "13px sans";
    
    for(let i = 0; i < s; i++) {
        for(let j = 0; j < s; j++) {
            x = i/s + 0.5/s;
            y = j/s + 0.5/s;
            
            x -= 0.5;
            y -= 0.5;
            
            
            x *= 2.8;
            y *= 2.8;
            
            let z,c;
            
            // Put to false for Julia
            let mandelbrot = true;
            
            if(mandelbrot){
            	x -= 0.5;
                z = new ComplexNumber(0.0, 0.0);
                c = new ComplexNumber(x,y);
                ct = 0.2 * Math.cos(time * pi2) + 0.2;
                c.times(0.5);
                c.r += -0.83;
                c.i -= 0.25;
            } else {
                z = new ComplexNumber(x,y);
                c = new ComplexNumber(0.4 + 0.2 * Math.cos(time * pi2), 0.001);
            }
            
            let k;
            
            for(k = 0; k < 25; k++){
            	z = z.pow2().add(c);
                if(z.len() > 4.0){
                	break;
                }
        	}
        
    		ctx.fillStyle = "rgba(0,100,0,"+(k/30 + 0.1)+")";
            x = i/s;
            y = j/s + 0.89/s;
            
            x *= canvas.width;
            y *= canvas.height;
            
            
            ctx.fillText(letters[j][i], x, y);
    	}
    }
    
    moveLetters();
    moveLetters();
}

Fluid gif