Fractal fractal

Fractal IFS text. Inspired by the 'CHAOS' fractal on Paul Bourke's site.
Letters look just as bad as my handwriting. Work in progress

Log in to post a comment.

// Forked from "Barnsley fern" by reinder

// https://turtletoy.net/turtle/7e604ce874
// Your word in all caps here (not too long)
var word = "FRACTAL";

Canvas.setpenopacity(-1);

const turtle = new Turtle();

let x = 0;
let y = 0;

function d2r(degrees){
  return degrees * (Math.PI/180);
}

function angle(thetha){
    return [[Math.cos(d2r(thetha)),-Math.sin(d2r(thetha))]
            ,[Math.sin(d2r(thetha)), Math.cos(d2r(thetha))]];
}

// Assuming 2x2 matrices as input
function mm(a, b){
    return [[a[0][0]*b[0][0] + a[0][1]*b[1][0], a[0][0]*b[0][1] + a[0][1]*b[1][1]],
            [a[1][0]*b[0][0] + a[1][1]*b[0][1], a[1][0]*b[0][1] + a[1][1]*b[1][1]]];
}

function stretch(x_scale, y_scale){
    return [[x_scale, 0.],
            [0., y_scale]];
}



var k = 2.0;
var scale = [[k, 0.],[0., k]];
var thickness = 0.07;
var length_factor = 0.065;

var letters = {
			"A": [[1.0*length_factor, thickness, 75, -0.125, 0.5],
					[1.0*length_factor, thickness, -65, 0.125, 0.8],
					[0.3*length_factor, thickness,0, 0, 0.45]],
			"B": [[1.0*length_factor, thickness, 90, -0.15, 0.5], 
					[0.35*length_factor, thickness, 90, 0.3, 0.77],
					[0.5*length_factor, thickness, 0, 0, 1.],
					[0.5*length_factor, thickness, 0, 0, 0.5],
					[0.5*length_factor, thickness, 0, 0, 0.125],
					[0.35*length_factor, thickness, 90, 0.4, 0.3]
					],
			"C": [[0.5*length_factor, thickness, 0, -0.125, 1.0],
					[0.5*length_factor, thickness,0, -0.125, 0.2],
					[1.0*length_factor, thickness, 90, -0.25, 0.5]],
			"D": [[0.5*length_factor, thickness, -15, -0.125, 1.0],
					[0.5*length_factor, thickness,15, -0.125, 0.125],
					[1.0*length_factor, thickness, 90, -0.25, 0.5],
					[0.9*length_factor, thickness, 90, 0.2, 0.5]],
			"E": [[0.5*length_factor, thickness, 0, 0., 1.0],
					[0.5*length_factor, thickness,0, 0, 0.2],
					[1.0*length_factor, thickness, 90, -0.125, 0.5],
					[0.3*length_factor, thickness,0, 0, 0.6]],
			"F": [[1.0*length_factor, thickness, 0, 0., 1.0],
					[0.5*length_factor, thickness,0, 0, 0.5],
					[1.0*length_factor, thickness, 90, -0.25, 0.5]],
			"G": [[1.0*length_factor, thickness, 90, -0.25, 0.5],
			        [0.5*length_factor, thickness, 0, -0.125, 1.0],
			        [0.5*length_factor, thickness,0, -0.125, 0.125],
			        [0.5*length_factor, thickness, 90, 0.25, 0.2],
			        [0.4*length_factor, thickness,0, 0, 0.5]],
			"H": [[1.0*length_factor, thickness, 90, -0.25, 0.5], 
			        [1.0*length_factor, thickness, 90, 0.25, 0.5],
			        [0.5*length_factor, thickness, 0, -0.125, 0.5]],
			"I": [[0.8*length_factor, thickness, 90, 0, 0.4], [0.1*length_factor, thickness, 0, -0.125, 1.]],
			"J": [[0.5*length_factor, thickness, 0, 0.125, 1.0],
					[1.0*length_factor, thickness, 90, 0.25, 0.5],
					[0.5*length_factor, thickness, 0, 0.125, 0.0],
					[0.5*length_factor, thickness, 90, -0.25, 0.125]],
			"K": [[1.0*length_factor, thickness, 90, -0.25, 0.5],
			        [0.7*length_factor, thickness, 45., 0., 0.7], 
			        [0.7*length_factor, thickness, -45., 0., 0.5]],
			"L": [[0.5*length_factor, thickness, 0, -0.125, 0.125],
					[1.0*length_factor, thickness, 90, -0.25, 0.5]],
			"M": [[1.0*length_factor, thickness, 90, -0.3, 0.5],
			        [1.0*length_factor, thickness, 90, 0.45, 0.5],
			        [0.5*length_factor, thickness, 70., 0.2, 0.76],
			        [0.7*length_factor, thickness, -70., -0.25, 0.88]],
			"N": [[1.0*length_factor, thickness, 90, -0.25, 0.5],
			        [1.0*length_factor, thickness, 90, 0.2, 0.5],
			        [0.8*length_factor, thickness, -75., -0.25, 0.85]],
			"O": [[0.7*length_factor, thickness, 0, -.125, 1.0],
					[0.7*length_factor, thickness,0,  -.125, 0.25],
					[1.0*length_factor, thickness, 90, -0.25, 0.5],
					[1.0*length_factor, thickness, 90, 0.25, 0.5]],
			"P": [[1.0*length_factor, thickness, 90, -0.15, 0.5], 
					[0.35*length_factor, thickness, 90, 0.4, 0.77],
					[0.5*length_factor, thickness, 0, 0, 1.],
					[0.5*length_factor, thickness, 0, 0, 0.5]],
			"Q": [[0.7*length_factor, thickness, 0, -.125, 1.0],
					[0.7*length_factor, thickness,0,  -.125, 0.25],
					[1.0*length_factor, thickness, 90, -0.25, 0.5],
					[1.0*length_factor, thickness, 90, 0.25, 0.5],
					[0.7*length_factor, thickness, -45., 0., 0.5]],
			"R": [[1.0*length_factor, thickness, 90, -0.15, 0.5], 
					[0.35*length_factor, thickness, 90, 0.4, 0.77],
					[0.5*length_factor, thickness, 0, 0, 1.],
					[0.5*length_factor, thickness, 0, 0, 0.5],
					[0.7*length_factor, thickness, -30, 0.0, 0.35]],
			"S": [[0.7*length_factor, thickness, 0, -.125, 1.0],
					[0.7*length_factor, thickness,0,  -.125, 0.],
					[0.5*length_factor, thickness, 90, -.25, 0.8],
					[0.7*length_factor, thickness,0,  -.125, 0.5],
					[0.5*length_factor, thickness, 90, .25, 0.2]],
			"T": [[1.0*length_factor, thickness, 0, -0.125, 1.0],
					[0.8*length_factor, thickness, 90, 0.125, 0.5]],
			"U": [	[0.7*length_factor, thickness,0,  -.125, 0.25],
					[1.0*length_factor, thickness, 90, -0.25, 0.5],
					[1.0*length_factor, thickness, 90, 0.25, 0.5]],
			"V": [[1.0*length_factor, thickness, -70, -0.25, 0.7],
					[1.0*length_factor, thickness, 70, 0.25, 0.5]],
			"W": [[1.0*length_factor, thickness, 100, -0.3, 0.5],
			        [1.0*length_factor, thickness, 80, 0.3, 0.5],
			        [0.7*length_factor, thickness, -70., 0., 0.6],
			        [0.7*length_factor, thickness, 70., -.125, 0.4]],
			"X": [[1.*length_factor, thickness, 45., 0., 0.5], 
			        [1.0*length_factor, thickness, -45., 0., 0.6]],
			"Y": [[1.0*length_factor, thickness, -70, -0.25, 0.7],
					[1.0*length_factor, thickness, 70, 0.25, 0.5],
					[0.6*length_factor, thickness, 90, 0.1, 0.125]],
			"Z": [[0.7*length_factor, thickness, 0, -.125, 1.0],
                    [0.7*length_factor, thickness,0, -.125, 0.25],
                    [0.7*length_factor, thickness, 55, 0, 0.6]] // Thanks Akash
			};



for (const [key, value] of Object.entries(letters)) {
    let new_entry = [];
    for(let i =0; i<value.length;i++){
        let segment = value[i];
        let t = mm(mm(angle(segment[2]),stretch(segment[0],segment[1])), scale);
        new_entry.push([t[0][0], t[0][1], t[1][0], t[1][1], segment[3]*k, segment[4]*k]);
    }
    letters[key] = new_entry;
}


function calculate_offset(param, idx, total_length, margin) {
    let half_len = (total_length-1)*0.5;
    var ret_param = [];
    for(let i =0; i<param.length;i++){
        //How do I clone (or write javascript?)
        ret_param.push([param[i][0], param[i][1], param[i][2], param[i][3], param[i][4] - half_len + idx + idx*margin, param[i][5]]);
    }
    return ret_param;
}
			
params = [];


for(let i =0; i<word.length;i++){
    console.log();
    let param = calculate_offset(letters[word[i]], i, word.length, 1.0);
    for(let j =0; j<param.length;j++){
        params.push(param[j]);
    }
}


function walk(i) {
    turtle.pendown();
    
    
    
    turtle.jump(-35 + x * 14, 15 - y * 14);
    turtle.circle(0.1);
    
    const r = Math.random();
    
    let cumulative_p = 0.;
    
    
    for(let i =0; i<params.length;i++){
        cumulative_p = cumulative_p + 1/params.length;
        
        if(r<cumulative_p){
            let a = params[i][0];
            let b = params[i][1];
            let c = params[i][2];
            let d = params[i][3];
            let e = params[i][4];
            let f = params[i][5];
            [x,y] = [a*x + b*y + e, c*x + d*y + f];
            break;
        }
    }

    return i < 100000;
}