My take on Rev Dan Catt's revdancatt.com/2020/…-snowflake-generator
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(-.8); // Global code will be evaluated once. const turtle = new Turtle(); const n = 6; // min=1, max=20, step=1 const nTwigs = 6 // min=3, max=30, step=1 const pFlip = .5; // min=0, max=1, step=0.01 const pMutate = .5; // min=0, max=1, step=0.01 const pTriangleOverHexagon = .5; // min=0, max=1, step=0.01 const randomHeading = 1; //min=0, max=1, step=1 // The walk function will be called until it returns false. function walk(i) { let size = 150 / n; for(let x = (100 / n); x < 200; x+=200/n) { for(let y = (100 / n); y < 200; y+=200/n) { turtle.jump(x - 100, y - 100); turtle.seth(randomHeading == 0? 0: randn_bm(1, 360)); flake(size * randn_bm(0.2, 1.5), nTwigs, pFlip, pMutate, pTriangleOverHexagon); } } return false; } function flake(size, nTwigs, pFlip, pMutate, pTriangleOverHexagon) { let twigLength = size / 2; let nBranches = Math.floor(randn_bm(1, 13)); let twigBranches = branch(nBranches, pFlip, pMutate, pTriangleOverHexagon); let twigRatios = []; for(let i = 0; i < nBranches; i++) { twigRatios[i] = randn_bm(0,1, 1.3); } let twigOrigins = []; for(let i = 0; i <= nBranches; i++) { twigOrigins[i] = randn_bm(0, 10); } twigOrigins = normalize(twigOrigins); for(let sym = 0; sym < nTwigs; sym++) { for(let i = 0; i < nBranches; i++) { turtle.forward(twigOrigins[i] * twigLength); twigBranches[i](twigLength * twigRatios[i] * ( 1 - (i/nBranches) )); if(i == nBranches - 1) { turtle.forward(twigOrigins[nBranches] * twigLength); } } turtle.up(); turtle.backward(twigLength); turtle.down(); turtle.right(360 / nTwigs); } } function branch(n, pFlip, pMutate, pTriangleOverHexagon) { let b = []; let simpleLine = function(length, direction) { turtle.down(); if(direction > 0) { turtle.left(180); } turtle.right(60); turtle.forward(length); turtle.up(); turtle.backward(length); turtle.left(120); turtle.down(); turtle.forward(length); turtle.up(); turtle.backward(length); turtle.right(60); if(direction > 0) { turtle.left(180); } turtle.down(); } let triangle = function(length, direction) { turtle.down(); if(direction > 0) { turtle.left(180); } turtle.left(30); turtle.forward(length); turtle.right(120); turtle.forward(length); turtle.right(120); turtle.forward(length); turtle.right(150); if(direction > 0) { turtle.left(180); } } let hexagon = function(length, direction) { turtle.up(); turtle.forward(length / 2); turtle.right(60); turtle.down(); for(let i = 0; i < 6; i++) { turtle.right(60); turtle.forward(length / 2); } turtle.left(60); turtle.up(); turtle.backward(length / 2); turtle.down(); } for(let i = 0; i < n; i++) { let f = Math.random(0, 1) > pMutate? simpleLine: (Math.random(0, 1) < pTriangleOverHexagon? triangle: hexagon); b[i] = Math.random(0, 1) < pFlip? function (l) { f(l, 1); } : function(l) { f(l, -1); } ; } return b; } function normalize(inArray) { let sum = inArray.reduce((a, b) => a + b, 0); let outArray = []; for(let i = 0; i < inArray.length; i++) { outArray[i] = inArray[i] / sum; } return outArray; } // function below is normal distribution radmon generator // https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve#49434653 // by joshuakcockrell answered Mar 22 '18 at 17:14 function randn_bm(min, max, skew = 1) { let u = 0, v = 0; while(u === 0) u = Math.random() //Converting [0,1) to (0,1) while(v === 0) v = Math.random() let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v ) num = num / 10.0 + 0.5 // Translate to 0 -> 1 if (num > 1 || num < 0) num = randn_bm(min, max, skew) // resample between 0 and 1 if out of range else{ num = Math.pow(num, skew) // Skew num *= max - min // Stretch to fill range num += min // offset to min } return num }