Variations:
Short walks in a barrel πΆπ½ (variation)
Short walks in a barrel πΆπ½ (variation)
Short walks in a barrel πΆπ½ (variation)
Short walks in a barrel πΆπ½ (variation)
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(.7); const grid = 65; //min=1 max=200 step=1 const maxWanderLength = 40; //min=2 max=100 step=1 const wander = 0; //min=0 max=2 step=1 (Orthogonal, Diagonal, Both) const border = 15; //min=0 max=90 step=1 const drawBorder = 1; //min=0 max=1 step=1 (No, Yes) const barrelEffect = -.28; //min=-1 max=10 step=.01 const scaleToFitEffect = 0 //min=0 max=1 step=1 (No, Yes) // Global code will be evaluated once. const turtle = new Turtle();//Tortoise().addTransform(); const cellSize = (200 - border - border) / grid; let tiles = Array.from({length: grid**2}, (v,k) => k); const effect = Barrel(barrelEffect); let effectScalar = 1; if(scaleToFitEffect == 1) { let max = [0, 0]; const halfPixels = cellSize * grid/2; for(let x = -halfPixels; x <= halfPixels; x++) { for(let y = -halfPixels; y <= halfPixels; y++) { let pt = effect([x, y]); max = [Math.max(max[0], pt[0]), Math.max(max[1], pt[1])]; } } effectScalar = Math.max(halfPixels / max[0], halfPixels / max[1]); } const scale2 = (a, s) => [a[0]*s,a[1]*s]; const t = (c, r) => scale2(effect([(c + .5) * cellSize - 100 + border, (r + .5) * cellSize - 100 + border]), effectScalar); function segment_intersect2(a,b,d,c) { const e=(c[1]-d[1])*(b[0]-a[0])-(c[0]-d[0])*(b[1]-a[1]); if(0==e)return false; c=((c[0]-d[0])*(a[1]-d[1])-(c[1]-d[1])*(a[0]-d[0]))/e; d=((b[0]-a[0])*(a[1]-d[1])-(b[1]-a[1])*(a[0]-d[0]))/e; return 0<=c&&1>=c&&0<=d&&1>=d?[a[0]+c*(b[0]-a[0]),a[1]+c*(b[1]-a[1])]:false; } const border_intersect2 = ((border) => { const borders = [[border - 100, border - 100], [100 - border, border - 100], [100 - border, 100 - border], [border - 100, 100 - border]]; return (a, b) => { let pt = false; for(let i = 0; pt === false && i < borders.length; i++) { pt = segment_intersect2(borders[i], borders[(i+1) % borders.length], a, b); } return pt; } })(border) const isOutOfBounds = ((border) => { return (pt) => pt[0] < (border - 100) || (100 - border) < pt[0] || pt[1] < (border - 100) || (100 - border) < pt[1] })(border) if(drawBorder == 1) { const borderTurtle = new Turtle(); borderTurtle.jump(border / 2 - 100, border / 2 - 100); borderTurtle.goto(100 - border / 2, border / 2 - 100); borderTurtle.goto(100 - border / 2, 100 - border / 2); borderTurtle.goto(border / 2 - 100, 100 - border / 2); borderTurtle.goto(border / 2 - 100, border / 2 - 100); } // The walk function will be called until it returns false. function walk(i) { // console.log('d', border_intersect2([0, -100], [100, 100])); let chosen = tiles.sort((a,b) => Math.random() < .5? -1: 1).pop(); for(let i = 0; i < maxWanderLength; i++) { let column = chosen % grid; let row = chosen / grid | 0; let cp = turtle.pos(); let pt = t(column, row); let cpOoB = isOutOfBounds(cp); let ptOoB = isOutOfBounds(pt); if(i == 0) { turtle.jump(pt); } else if(ptOoB) { if(!cpOoB) turtle.goto(border_intersect2(pt, cp)); turtle.jump(pt); } else if(cpOoB) { turtle.jump(ptOoB? pt: border_intersect2(pt, cp)); } turtle.goto(pt); tiles = tiles.filter((i) => i != chosen); const orthogonalCandidates = [[column, row + 1], [column + 1, row], [column, row - 1],[column - 1, row]]; const diagonalCandidates = [[column - 1, row - 1], [column + 1, row - 1], [column - 1, row + 1], [column + 1, row + 1]]; const candidates = (wander == 0? orthogonalCandidates: wander == 1? diagonalCandidates: [...orthogonalCandidates, ...diagonalCandidates]) .filter((i) => i[0] >= 0 && i[0] < grid && i[1] >= 0 && i[1] < grid) .map((i) => i[1] * grid + i[0]) .filter((i) => tiles.includes(i)); if(candidates.length == 0) break; chosen = candidates.sort((a,b) => Math.random() < .5? -1: 1).pop() } return tiles.length > 0; } //Barrel effect shamelessly copied from Reinder's https://turtletoy.net/turtle/102cbd7c4d function Barrel(b) { return p => { let s = (1+(p[0]**2 + p[1]**2)*b/1e4); return [p[0]*s, p[1]*s]; } }