Wang tiles: tubes

16 tiles

Log in to post a comment.

const SIZE = 12; // min=10, max=20, step=1

const cell = 200 / SIZE
const cell_r = cell / 2

Canvas.setpenopacity(1);

const t = new Turtle();

const tube_r = cell * 0.25
const tube_r2 = cell * 0.3
const seam_r = cell * 0.05
const cross_r = seam_r

function draw_tile(x, y, left, up, right, down) {
    let x0 = -100 + x * cell
    let x1 = x0 + cell
    let cx = x0 + cell_r
    let y0 = -100 + y * cell
    let y1 = y0 + cell
    let cy = y0 + cell_r

    // common: seams
    
    if (left) {
        t.jump(x0, y0 + cell_r - tube_r2)
        t.goto(x0 + seam_r, y0 + cell_r - tube_r2)
        t.goto(x0 + seam_r, y0 + cell_r + tube_r2)
        t.goto(x0, y0 + cell_r + tube_r2)
    }
    
    if (right) {
        t.jump(x1, y0 + cell_r - tube_r2)
        t.goto(x1 - seam_r, y0 + cell_r - tube_r2)
        t.goto(x1 - seam_r, y0 + cell_r + tube_r2)
        t.goto(x1, y0 + cell_r + tube_r2)
    }

    if (up) {    
        t.jump(x0 + cell_r - tube_r2, y0)
        t.goto(x0 + cell_r - tube_r2, y0 + seam_r)
        t.goto(x0 + cell_r + tube_r2, y0 + seam_r)
        t.goto(x0 + cell_r + tube_r2, y0)
    }
    
    if (down) {
        t.jump(x0 + cell_r - tube_r2, y1)
        t.goto(x0 + cell_r - tube_r2, y1 - seam_r)
        t.goto(x0 + cell_r + tube_r2, y1 - seam_r)
        t.goto(x0 + cell_r + tube_r2, y1)
    }
    
    // common: bckg

    // t.jump(x0, y0)
    // t.goto(x0 + cross_r, y0 + cross_r)

    // t.jump(x0, y1)
    // t.goto(x0 + cross_r, y1 - cross_r)

    // t.jump(x1, y0)
    // t.goto(x1 - cross_r, y0 + cross_r)

    // t.jump(x1, y1)
    // t.goto(x1 - cross_r, y1 - cross_r)

    // 0 sides
    
    if (!left && !up && !right && !down) {
    }
    
    // 1 side
    
    if (left && !up && !right && !down) {
        t.jump(x0 + seam_r, cy - tube_r)
        t.setheading(0)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 180)
        t.forward(cell_r - seam_r)
    }

    if (!left && up && !right && !down) {
        t.jump(cx + tube_r, y0 + seam_r)
        t.setheading(90)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 180)
        t.forward(cell_r - seam_r)
    }

    if (!left && !up && right && !down) {
        t.jump(x1 - seam_r, cy + tube_r)
        t.setheading(180)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 180)
        t.forward(cell_r - seam_r)
    }

    if (!left && !up && !right && down) {
        t.jump(cx - tube_r, y1 - seam_r)
        t.setheading(-90)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 180)
        t.forward(cell_r - seam_r)
    }
    
    // 2 sides straight

    if (left && !up && right && !down) {
        t.jump(x0 + seam_r, cy - tube_r)
        t.goto(x1 - seam_r, cy - tube_r)

        t.jump(x0 + seam_r, cy + tube_r)
        t.goto(x1 - seam_r, cy + tube_r)
    }

    if (!left && up && !right && down) {
        t.jump(cx - tube_r, y0 + seam_r)
        t.goto(cx - tube_r, y1 - seam_r)

        t.jump(cx + tube_r, y0 + seam_r)
        t.goto(cx + tube_r, y1 - seam_r)
    }

    // 2 sides turn

    if (left && up && !right && !down) {
        t.jump(cx + tube_r, y0 + seam_r)
        t.setheading(90)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 90)
        t.forward(cell_r - seam_r)

        t.jump(cx - tube_r, y0 + seam_r)
        t.setheading(90)
        t.forward(2 * seam_r)
        t.circle(cell_r - tube_r - 3 * seam_r, 90)
        t.forward(2 * seam_r)
    }

    if (!left && up && right && !down) {
        t.jump(x1 - seam_r, cy + tube_r)
        t.setheading(180)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 90)
        t.forward(cell_r - seam_r)

        t.jump(x1 - seam_r, cy - tube_r)
        t.setheading(180)
        t.forward(2 * seam_r)
        t.circle(cell_r - tube_r - 3 * seam_r, 90)
        t.forward(2 * seam_r)
    }

    if (!left && !up && right && down) {
        t.jump(cx - tube_r, y1 - seam_r)
        t.setheading(-90)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 90)
        t.forward(cell_r - seam_r)

        t.jump(cx + tube_r, y1 - seam_r)
        t.setheading(-90)
        t.forward(2 * seam_r)
        t.circle(cell_r - tube_r - 3 * seam_r, 90)
        t.forward(2 * seam_r)
    }

    if (left && !up && !right && down) {
        t.jump(x0 + seam_r, cy - tube_r)
        t.setheading(0)
        t.forward(cell_r - seam_r)
        t.circle(tube_r, 90)
        t.forward(cell_r - seam_r)

        t.jump(x0 + seam_r, cy + tube_r)
        t.setheading(0)
        t.forward(2 * seam_r)
        t.circle(cell_r - tube_r - 3 * seam_r, 90)
        t.forward(2 * seam_r)
    }

    // 3 sides
    
    if (left && up && right && !down) {
        t.jump(x0 + seam_r, cy + tube_r)
        t.goto(x1 - seam_r, cy + tube_r)
        
        t.jump(x0 + seam_r, cy - tube_r)
        t.goto(cx - tube_r, cy - tube_r)
        t.goto(cx - tube_r, y0 + seam_r)

        t.jump(x1 - seam_r, cy - tube_r)
        t.goto(cx + tube_r, cy - tube_r)
        t.goto(cx + tube_r, y0 + seam_r)
        
        t.jump(cx + tube_r, cy - tube_r)
        t.setheading(150)
        t.circle(2 * tube_r, 60)
    }

    if (!left && up && right && down) {
        t.jump(cx - tube_r, y0 + seam_r)
        t.goto(cx - tube_r, y1 - seam_r)
        
        t.jump(cx + tube_r, y0 + seam_r)
        t.goto(cx + tube_r, cy - tube_r)
        t.goto(x1 - seam_r, cy - tube_r)

        t.jump(cx + tube_r, y1 - seam_r)
        t.goto(cx + tube_r, cy + tube_r)
        t.goto(x1 - seam_r, cy + tube_r)
        
        t.jump(cx + tube_r, cy + tube_r)
        t.setheading(-120)
        t.circle(2 * tube_r, 60)
    }

    if (left && !up && right && down) {
        t.jump(x0 + seam_r, cy - tube_r)
        t.goto(x1 - seam_r, cy - tube_r)
        
        t.jump(x0 + seam_r, cy + tube_r)
        t.goto(cx - tube_r, cy + tube_r)
        t.goto(cx - tube_r, y1 - seam_r)

        t.jump(x1 - seam_r, cy + tube_r)
        t.goto(cx + tube_r, cy + tube_r)
        t.goto(cx + tube_r, y1 - seam_r)
        
        t.jump(cx - tube_r, cy + tube_r)
        t.setheading(-30)
        t.circle(2 * tube_r, 60)
    }

    if (left && up && !right && down) {
        t.jump(cx + tube_r, y0 + seam_r)
        t.goto(cx + tube_r, y1 - seam_r)
        
        t.jump(cx - tube_r, y0 + seam_r)
        t.goto(cx - tube_r, cy - tube_r)
        t.goto(x0 + seam_r, cy - tube_r)

        t.jump(cx - tube_r, y1 - seam_r)
        t.goto(cx - tube_r, cy + tube_r)
        t.goto(x0 + seam_r, cy + tube_r)
        
        t.jump(cx - tube_r, cy - tube_r)
        t.setheading(60)
        t.circle(2 * tube_r, 60)
    }

    // 4 sides

    if (left && up && right && down) {
        t.jump(cx - tube_r, y0 + seam_r)
        t.goto(cx - tube_r, cy - tube_r)
        t.goto(x0 + seam_r, cy - tube_r)

        t.jump(cx - tube_r, y1 - seam_r)
        t.goto(cx - tube_r, cy + tube_r)
        t.goto(x0 + seam_r, cy + tube_r)

        t.jump(cx + tube_r, y0 + seam_r)
        t.goto(cx + tube_r, cy - tube_r)
        t.goto(x1 - seam_r, cy - tube_r)

        t.jump(cx + tube_r, y1 - seam_r)
        t.goto(cx + tube_r, cy + tube_r)
        t.goto(x1 - seam_r, cy + tube_r)

        if (random_bool()) {
            t.jump(cx - tube_r, cy - tube_r)
            t.setheading(60)
            t.circle(2 * tube_r, 60)
            
            t.jump(cx + tube_r, cy + tube_r)
            t.setheading(-120)
            t.circle(2 * tube_r, 60)
        }
        else {
            t.jump(cx - tube_r, cy + tube_r)
            t.setheading(-30)
            t.circle(2 * tube_r, 60)
            
            t.jump(cx + tube_r, cy - tube_r)
            t.setheading(150)
            t.circle(2 * tube_r, 60)
        }
    }
}

function random_bool() {
    return (Math.random() < 0.5)
}

let prev_down = []
for (let i = 0; i < SIZE; i++) {
    prev_down[i] = random_bool()
}

let prev_right = random_bool()

for (let y = 0; y < SIZE; y++) {
    for (let x = 0; x < SIZE; x++) {
        let new_down = random_bool()
        let new_right = random_bool()
        
        draw_tile(x, y, prev_right, prev_down[x], new_right, new_down)
        
        prev_right = new_right
        prev_down[x] = new_down
    }
}