JSFiddle - React, Tailwind, and code Playground

by jcubed111

HTML

<canvas id="main" width=500 height=500></canvas>

CSS

body{
    background: #282833;
}

JavaScript

const s = 50;
const minDist = s/Math.SQRT2 * 0.9;

const dist = ({x: x1, y: y1}, {x: x2, y: y2}) => Math.sqrt((x1-x2)**2 + (y1-y2)**2);
const add = ({x: x1, y: y1}, {x: x2, y: y2}) => ({x: x1 + x2, y: y1 + y2});
const diff = ({x: x1, y: y1}, {x: x2, y: y2}) => ({x: x1 - x2, y: y1 - y2});
const scale = ({x, y}, s) => ({x: x*s, y: y*s});
const rot = ({x, y}, angle) => {
	let cosr = Math.cos(angle);
    let sinr = Math.sin(angle);
    return {x: cosr * x + -sinr * y, y: sinr * x + cosr * y};
};
const randInt = (a, b) => Math.floor(Math.random() * (b - a) + a);
const randChoice = (a) => a[randInt(0, a.length)];
const shuffled = a => a.sort(_ => 0.5 - Math.random());


let branches = [];
let points = [];
let rejects = [];

function checkPoint(p1) {
	return !points.some(p2 => dist(p1, p2) < minDist);
}

function turnChoices(currentAngle, chanceZero = 0) {
	let choices = ({
    	'-3': [1, 2, 2],
        '-2': [1, 1, 1, 2, 0],
        '-1': [-1, 1, 1, 0],
         '0': [-1, 1, 0, 0],
         '1': [1, -1, -1, 0],
         '2': [-1, -1, -1, -2, 0],
         '3': [-1, -2, -2],
    })[currentAngle];
	let numZeros = chanceZero * choices.length / (1.0 - chanceZero);
    return [...choices, ...Array(Math.round(numZeros)).fill(0)];
}

function branchChoices(currentAngle) {
	return ({
    	'-3': [-1],
        '-2': [-1, 0],
        '-1': [-3, 0, 0, 1, 1],
         '0': [-2, -2, -1, 1, 2, 2],
         '1': [3, 0, 0, -1, -1],
         '2': [1, 0],
         '3': [1],
    })[currentAngle];
}

function makeBranch(start, size, angle) {
	if(size == 0) return false;
    let stepVec = rot({x: 0, y: s}, Math.PI*0.25*angle);
	let newBranch = [start];
    let angles = [angle];
	for(let i=size-1; i>=0; i--) {
        let currentPoint = newBranch[newBranch.length-1];
    	let nextPoint = add(currentPoint, stepVec);
        angles.push(angle);
        if(!checkPoint(nextPoint)) {
            rejects.push([currentPoint, nextPoint]);
        	break;
        }
    	newBranch.push(nextPoint);
    ...