Wanted: en.wikipedia.org/wiki/wanted_(2008_film)
(If you don't see the effect, hit "Compile & Run" a couple of times on the same mode while staring at the image (in rounded mode you still might need to search)).
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(.7);
const mode = 2; // min=0, max=3, step=1 (Rounded, Cornered, Classic, Random)
const tileSize = 15; // min=2, max=40, step=1
const threadSize = .55; // min=0, max=.9, step=.05
class Grid {
constructor(tileSize) {
this.size = tileSize;
this.half = this.size / 2;
this.centers = [];
let nTiles = Math.ceil(100 / this.size);
for(let i = Math.floor((nTiles) * -this.size); i <= Math.floor((nTiles) * this.size); i += this.size) {
this.centers.push(i);
}
this.gridSize = this.centers.length;
}
draw(t) {
for(let i = 0; i < this.gridSize; i++) {
turtle.jump(this.centers[i] - this.half, -110);
turtle.goto(this.centers[i] - this.half, 110);
turtle.jump(-110, this.centers[i] - this.half);
turtle.goto(110, this.centers[i] - this.half);
}
}
getCenterFor(column, row) {
return [this.centers[column], this.centers[row]];
}
}
// Global code will be evaluated once.
const turtle = new Turtle();
const grid = new Grid(tileSize);
//grid.draw(turtle);
const delta = (tileSize * threadSize) / 2
// The walk function will be called until it returns false.
function walk(i) {
let col = i % grid.gridSize;
let row = i / grid.gridSize | 0;
let tile = grid.getCenterFor(col, row);
turtle.jump(tile[0], tile[1] - 2);
switch(mode) {
case 0:
roundedThread(col, row, grid, tile, delta);
break;
case 1:
cornerThread(col, row, grid, tile, delta);
break;
case 2:
loom(col, row, grid, tile, delta);
break;
case 3:
random(col, row, grid, tile, delta);
break;
}
return i < (grid.gridSize * grid.gridSize);
}
const mistakeRow = Math.ceil(Math.random() * (grid.gridSize - 4)) + 2;
const mistakeCol = Math.ceil(Math.random() * (grid.gridSize - 4)) + 2;
function cornerThread(col, row, grid, tile, delta) {
if(col % 2 == 0) {
if(row % 2 == 0) {
crossVerticalOverHorizontal(grid, tile, delta, mistakeCol == col && mistakeRow == row);
} else {
diagonalBottomLeftToTopRight(grid, tile, delta, mistakeCol == col && mistakeRow == row);
}
} else if(row % 2 == 0) {
diagonalBottomRightToTopLeft(grid, tile, delta, mistakeCol == col && mistakeRow == row);
} else {
crossVerticalOverHorizontal(grid, tile, delta, mistakeCol == col && mistakeRow == row);
}
}
function roundedThread(col, row, grid, tile, delta) {
if(col % 2 == 0) {
if(row % 2 == 0) {
crossVerticalOverHorizontal(grid, tile, delta, mistakeCol == col && mistakeRow == row);
} else {
roundedBottomLeftToTopRight(grid, tile, delta, mistakeCol == col && mistakeRow == row);
}
} else if(row % 2 == 0) {
roundedBottomRightToTopLeft(grid, tile, delta, mistakeCol == col && mistakeRow == row);
} else {
crossVerticalOverHorizontal(grid, tile, delta, mistakeCol == col && mistakeRow == row);
}
}
function loom(col, row, grid, tile, delta) {
if(((col % 2) + row) % 2 == 0) {
crossHorizontalOverVertical(grid, tile, delta, mistakeCol == col && mistakeRow == row);
} else {
crossVerticalOverHorizontal(grid, tile, delta, mistakeCol == col && mistakeRow == row);
}
}
function random(col, row, grid, tile, delta) {
switch(Math.ceil(Math.random() * 6)) {
case 1:
crossVerticalOverHorizontal(grid, tile, delta);
break;
case 2:
diagonalBottomLeftToTopRight(grid, tile, delta);
break;
case 3:
diagonalBottomRightToTopLeft(grid, tile, delta);
break;
case 4:
crossHorizontalOverVertical(grid, tile, delta);
break;
case 5:
roundedBottomLeftToTopRight(grid, tile, delta);
break;
case 6:
roundedBottomRightToTopLeft(grid, tile, delta);
break;
}
}
function crossVerticalOverHorizontal(grid, tile, delta, mistake = false) {
if(mistake) { return crossHorizontalOverVertical(grid, tile, delta); }
//vertical
turtle.jump(tile[0] - delta, tile[1] - grid.half);
turtle.goto(tile[0] - delta, tile[1] + grid.half);
turtle.jump(tile[0] + delta, tile[1] - grid.half);
turtle.goto(tile[0] + delta, tile[1] + grid.half);
//horizontal
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.goto(tile[0] - delta, tile[1] - delta);
turtle.jump(tile[0] + grid.half, tile[1] - delta);
turtle.goto(tile[0] + delta, tile[1] - delta);
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.goto(tile[0] - delta, tile[1] + delta);
turtle.jump(tile[0] + grid.half, tile[1] + delta);
turtle.goto(tile[0] + delta, tile[1] + delta);
}
function crossHorizontalOverVertical(grid, tile, delta, mistake = false) {
if(mistake) { return crossVerticalOverHorizontal(grid, tile, delta); }
//horizontal
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.goto(tile[0] + grid.half, tile[1] - delta);
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.goto(tile[0] + grid.half, tile[1] + delta);
//vertical
turtle.jump(tile[0] - delta, tile[1] - grid.half);
turtle.goto(tile[0] - delta, tile[1] - delta);
turtle.jump(tile[0] - delta, tile[1] + grid.half);
turtle.goto(tile[0] - delta, tile[1] + delta);
turtle.jump(tile[0] + delta, tile[1] - grid.half);
turtle.goto(tile[0] + delta, tile[1] - delta);
turtle.jump(tile[0] + delta, tile[1] + grid.half);
turtle.goto(tile[0] + delta, tile[1] + delta);
}
function diagonalBottomLeftToTopRight(grid, tile, delta, mistake = false) {
if(mistake) { return diagonalBottomRightToTopLeft(grid, tile, delta); }
//inside
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.goto(tile[0] - delta, tile[1] - grid.half);
turtle.jump(tile[0] + grid.half, tile[1] + delta);
turtle.goto(tile[0] + delta, tile[1] + grid.half);
//outside-top
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.goto(tile[0] - grid.half + (delta / 2), tile[1] + delta);
turtle.goto(tile[0] + delta, tile[1] - grid.half + (delta / 2));
turtle.goto(tile[0] + delta, tile[1] - grid.half);
let maxx = tile[0] + delta;
let maxy = tile[1] + delta;
//outside-bottom
turtle.jump(tile[0] + grid.half, tile[1] - delta);
if(tile[0] + grid.half - (delta / 2) < maxx) {
turtle.goto(maxx, tile[1] - delta);
turtle.jump(tile[0] - delta, maxy);
} else {
turtle.goto(tile[0] + grid.half - (delta / 2), tile[1] - delta);
turtle.goto(tile[0] - delta, tile[1] + grid.half - (delta / 2));
}
turtle.goto(tile[0] - delta, tile[1] + grid.half);
}
function diagonalBottomRightToTopLeft(grid, tile, delta, mistake = false) {
if(mistake) { return diagonalBottomLeftToTopRight(grid, tile, delta); }
//inside
turtle.jump(tile[0] + grid.half, tile[1] - delta);
turtle.goto(tile[0] + delta, tile[1] - grid.half);
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.goto(tile[0] - delta, tile[1] + grid.half);
//outside-bottom
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.goto(tile[0] - grid.half + (delta / 2), tile[1] - delta);
turtle.goto(tile[0] + delta, tile[1] + grid.half - (delta / 2));
turtle.goto(tile[0] + delta, tile[1] + grid.half);
let maxx = tile[0] + delta;
let miny = tile[1] - delta;
//outside-top
turtle.jump(tile[0] + grid.half, tile[1] + delta);
if(tile[0] + grid.half - (delta / 2) < maxx) {
turtle.goto(maxx, tile[1] + delta);
turtle.jump(tile[0] - delta, miny);
} else {
turtle.goto(tile[0] + grid.half - (delta / 2), tile[1] + delta);
turtle.goto(tile[0] - delta, tile[1] - grid.half + (delta / 2));
}
turtle.goto(tile[0] - delta, tile[1] - grid.half);
}
var angles = [90];
var r = grid.half + delta;
if(Math.sqrt(grid.size * grid.size * 2) < r * 2) {
angles = [];
let aa = (180 / Math.PI) * Math.acos(Math.sqrt(grid.size * grid.size * 2) / (r*2));
angles.push(45 - aa);
angles.push(aa * 2);
angles.push(45 - aa);
}
function roundedBottomLeftToTopRight(grid, tile, delta, mistake = false) {
if(mistake) { return roundedBottomRightToTopLeft(grid, tile, delta); }
//inside
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.setheading(0);
turtle.circle(-(grid.half - delta), 90)//tile[0] - delta, tile[1] - grid.half);
turtle.jump(tile[0] + grid.half, tile[1] + delta);
turtle.setheading(180);
turtle.circle(-(grid.half - delta), 90)//tile[0] - delta, tile[1] - grid.half);
//outside-top
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.setheading(0);
turtle.circle(-r, 90)//tile[0] - delta, tile[1] - grid.half);
//outside-bottom
turtle.jump(tile[0] + grid.half, tile[1] - delta);
turtle.setheading(180);
for(let i = 0; i < angles.length; i++) {
if(i%2 == 0) { turtle.pendown(); } else { turtle.penup(); }
turtle.circle(-r, angles[i])//tile[0] - delta, tile[1] - grid.half);
}
}
function roundedBottomRightToTopLeft(grid, tile, delta, mistake = false) {
if(mistake) { return roundedBottomLeftToTopRight(grid, tile, delta); }
//inside
turtle.jump(tile[0] + grid.half, tile[1] - delta);
turtle.setheading(180);
turtle.circle((grid.half - delta), 90)//tile[0] - delta, tile[1] - grid.half);
turtle.jump(tile[0] - grid.half, tile[1] + delta);
turtle.setheading(0);
turtle.circle((grid.half - delta), 90)//tile[0] - delta, tile[1] - grid.half);
//outside-top
turtle.jump(tile[0] + grid.half, tile[1] + delta);
turtle.setheading(180);
turtle.circle(r, 90)//tile[0] - delta, tile[1] - grid.half);
//outside-bottom
turtle.jump(tile[0] - grid.half, tile[1] - delta);
turtle.setheading(0);
for(let i = 0; i < angles.length; i++) {
if(i%2 == 0) { turtle.pendown(); } else { turtle.penup(); }
turtle.circle(r, angles[i])//tile[0] - delta, tile[1] - grid.half);
}
}