Actually, her thread built the labyrinth.
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(0.75); // Global code will be evaluated once. const turtle = new Turtle(); turtle.up(); const linesDrawn = []; class Line { constructor(x, y, a) { this.x1 = x; this.y1 = y; this.x2 = x; this.y2 = y; this.angle = a; this.x2 += Math.cos(a) * 0.1; this.y2 += Math.sin(a) * 0.1; this.collisionLines = new Set(); for (let line of lines) { if (this.raytoline(line) && line.raytoline(this)) { this.collisionLines.add(line); } } } anim() { if (Math.random() > 0.94) { const a = this.angle + (Math.random() > 0.5 ? Math.PI / 2 : -Math.PI / 2); const line = new Line( this.x2 + Math.cos(a) * 0.1, this.y2 + Math.sin(a) * 0.1, a ); lines.add(line); activeLines.add(line); } for (let line of this.collisionLines) { if (this !== line) { const collision = this.intersect(line); if (collision) { const x = collision.x; const y = collision.y; if ( Math.abs(x - this.x2) < Math.abs(x - line.x2) && Math.abs(y - this.y2) < Math.abs(y - line.y2) ) { this.draw(); activeLines.delete(this); } else { line.draw(); activeLines.delete(line); } } } } this.x2 += Math.cos(this.angle) * 0.3; this.y2 += Math.sin(this.angle) * 0.3; if (Math.abs(this.x2) > 100 || Math.abs(this.y2) > 100) { this.draw(); activeLines.delete(this); } } draw() { const line_hash = this.x1.toFixed(2) + "-" + this.y1.toFixed(2) + "-" + this.y2.toFixed(2) + "-" + this.y2.toFixed(2); if (!linesDrawn[line_hash]) { turtle.penup(); turtle.goto(this.x1, this.y1); turtle.pendown(); turtle.goto(this.x2, this.y2); linesDrawn[line_hash] = true; } } raytoline(line) { if ( (this.y2 - this.y1) / (this.x2 - this.x1) !== (line.y2 - line.y1) / (line.x2 - line.x1) ) { const d = (((this.x2 - this.x1) * (line.y2 - line.y1)) - (this.y2 - this.y1) * (line.x2 - line.x1)); if (d !== 0) { const r = (((this.y1 - line.y1) * (line.x2 - line.x1)) - (this.x1 - line.x1) * (line.y2 - line.y1)) / d; if (r >= 0) return true; } } return false; } intersect(line) { const td = this.x1 * this.y2 - this.y1 * this.x2; const ld = line.x1 * line.y2 - line.y1 * line.x2; const x = (td * (line.x1 - line.x2) - (this.x1 - this.x2) * ld) / ((this.x1 - this.x2) * (line.y1 - line.y2) - (this.y1 - this.y2) * (line.x1 - line.x2)); if (isNaN(x)) return false; const y = (td * (line.y1 - line.y2) - (this.y1 - this.y2) * ld) / ((this.x1 - this.x2) * (line.y1 - line.y2) - (this.y1 - this.y2) * (line.x1 - line.x2)); if (isNaN(y)) return false; if (this.x1 >= this.x2) { if (!(this.x2 - 0.01 <= x && x <= this.x1 + 0.01)) return false; } else { if (!(this.x1 - 0.01 <= x && x <= this.x2 + 0.01)) return false; } if (this.y1 >= this.y2) { if (!(this.y2 - 0.01 <= y && y <= this.y1 + 0.01)) return false; } else { if (!(this.y1 - 0.01 <= y && y <= this.y2 + 0.01)) return false; } if (line.x1 >= line.x2) { if (!(line.x2 - 0.01 <= x && x <= line.x1 + 0.01)) return false; } else { if (!(line.x1 - 0.01 <= x && x <= line.x2 + 0.01)) return false; } if (line.y1 >= line.y2) { if (!(line.y2 - 0.01 <= y && y <= line.y1 + 0.01)) return false; } else { if (!(line.y1 - 0.01 <= y && y <= line.y2 + 0.01)) return false; } return { x: x, y: y }; } } const lines = new Set(); const activeLines = new Set(); for (let j = 0; j < 3; j++) { const sx = Math.random() * 200 - 100; const sy = Math.random() * 200 - 100; for (let i = 0; i < 40; i++) { const a = Math.random() * 2 * Math.PI; const x = sx + (Math.random() - 0.5) * 200 * 0.05; const y = sy + (Math.random() - 0.5) * 200 * 0.05; let line = new Line(x, y, a, 90); lines.add(line); activeLines.add(line); line = new Line(x, y, a + Math.PI, 90); lines.add(line); activeLines.add(line); } } // The walk function will be called until it returns false. function walk(i) { for (let line of activeLines) { line.anim(); } return activeLines.size > 0; }