Forked from "Let it snow ❄️" by Jurgen Let it snow ❄️
Added back in Schotter? (shot?) noise with slider
Log in to post a comment.
// Forked from "Let it snow ❄️" by Jurgen
// https://turtletoy.net/turtle/8314202b5f
// 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
const schotter = 0; //min=0, max=1, step=0.01
// 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) {
let schotterX = 0;
let schotterY = 0;
schotterX = (Math.random() * size - size / 2) * n * schotter;
schotterY = (Math.random() * size - size / 2) * n * schotter;
turtle.jump(x - 100 + schotterX, y - 100 + schotterY);
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
}