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