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;
}