stitch pattern generator

diagonal billiard dash line on WxH grid -> two colours (iff W/H coprime)

Log in to post a comment.

Canvas.setpenopacity(-1);

const t = new Turtle();

const W = 87; // min=1, max=100, step=1
const H = 100; // min=1, max=100, step=1
const hatch_per_cell = 4; // min=1, max=10, step=1

let s = 200 / Math.max(W, H)

if (W > H) {
    x0 = -100
    y0 = -s * H/2
}
else {
    x0 = -s * W/2
    y0 = -100
}

const cells = []
for (let i = 0; i < W; i++) {
    cells[i] = []
    for (let j = 0; j < H; j ++) {
        cells[i][j] = false
    }
}

let x = 0, y = 0
let dx = +1, dy = +1
let mark = true

while (true) {
    cells[x][y] = mark
    mark = !mark
    
    let left = (x == 0) && (dx == -1)
    let right = (x == W - 1) && (dx == +1)
    let down = (y == 0) && (dy == -1)
    let up = (y == H - 1) && (dy == +1)
    
    if ((left || right) && (down || up)) {
        break
    }
    else if (left || right) {
        dx = -dx
        y += dy
    }
    else if (down || up) {
        dy = -dy
        x += dx
    }
    else {
        x += dx
        y += dy
    }
}

t.jump(x0, y0)
t.goto(-x0, y0)
t.goto(-x0, -y0)
t.goto(x0, -y0)
t.goto(x0, y0)

for (let i = 0; i < W; i++) {
    for (let j = 0; j < H; j++) {
        if (cells[i][j]) {
            if ((i + j) % 2 == 0) {
                t.jump(x0 + i * s, y0 + j * s)
                t.goto(x0 + (i + 1) * s, y0 + (j + 1) * s)
            }
            else {
                t.jump(x0 + (i + 1) * s, y0 + j * s)
                t.goto(x0 + i * s, y0 + (j + 1) * s)
            }
        }
    }
}

function gcd(x, y) {
    while (y > 0) {
        [x, y] = [y, x % y]
    }
    return x
}

if (gcd(W, H) == 1) {
    mark_u_0 = true
    mark_d_0 = true
    
    for (let j = 0; j < H; j++) {
        mark_u_0 = mark_d_0
        mark_d_0 = cells[0][j] ? !mark_u_0 : mark_u_0
        
        mark_u = mark_u_0
        mark_d = mark_d_0
        
        for (let i = 0; i < W; i++) {
            if (i > 0) {
                if ((i + j) % 2 == 0) {
                    mark_u = cells[i][j] ? !mark_d : mark_d
                }
                else {
                    mark_d = cells[i][j] ? !mark_u : mark_u
                }
            }
            
            if (mark_u && mark_d) {
                for (let k = 0; k < hatch_per_cell; k++) {
                    let y = y0 + j * s + s / hatch_per_cell * k
                    t.jump(x0 + i * s, y)
                    t.goto(x0 + (i + 1) * s, y)
                }
            }
            else {
                if (mark_u) {
                    if ((i + j) % 2 == 0) {
                        for (let k = 0; k < hatch_per_cell; k++) {
                            let ds = s / hatch_per_cell * k
                            let y = y0 + j * s + ds
                            t.jump(x0 + i * s + ds, y)
                            t.goto(x0 + (i + 1) * s, y)
                        }
                    }
                    else {
                        for (let k = 0; k < hatch_per_cell; k++) {
                            let ds = s / hatch_per_cell * k
                            let y = y0 + j * s + ds
                            t.jump(x0 + i * s, y)
                            t.goto(x0 + (i + 1) * s - ds, y)
                        }
                    }
                }
                
                if (mark_d) {
                    if ((i + j) % 2 == 0) {
                        for (let k = 0; k < hatch_per_cell; k++) {
                            let ds = s / hatch_per_cell * k
                            let y = y0 + j * s + ds
                            t.jump(x0 + i * s, y)
                            t.goto(x0 + i * s + ds, y)
                        }
                    }
                    else {
                        for (let k = 0; k < hatch_per_cell; k++) {
                            let ds = s / hatch_per_cell * k
                            let y = y0 + j * s + ds
                            t.jump(x0 + (i + 1) * s - ds, y)
                            t.goto(x0 + (i + 1) * s, y)
                        }
                    }
                }
            }
        }
    }
}