Grid

I wanted to try this kind of design for a while, so here it is. I know there are several examples of it already, but I need to figure it ! :)

Log in to post a comment.

// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(0.5);

const gridSize = 15;    //min = 1, max = 20, step = 1
const subdivisionX = 0; //min = 0, max = 20, step = 1
const subdivisionY = 15; //min = 0, max = 20, step = 1
let move = 40;          //min = 0, max = 100, step = 1
//const seed = 1;       //min = 1, max = 100, step = 1

const size = 160;       ////min = 100, max = 200, step = 1

const turtle = new Turtle();

const columns = [];

// we make the move value a percentage of the size of the tiles
move = move * (size / gridSize) / 100;

// A node is a point, one of the four corners of a tile. Each node knows where it's placed in the grid, which will be usefull.
class Node{
    constructor(x, y, line, column){
        this.x = x;
        this.y = y;
        this.line = line;
        this.column = column;
    }
    
    getX(){return this.x;}
    getY(){return this.y;}
    getPos(){return [this.x, this.y];}
    getLine(){return this.line;}
    getColumn(){return this.column;}
    
    shake(distance){
        this.x += Math.random() * distance * 2 - distance;
        this.y += Math.random() * distance * 2 - distance;
    }

}

// A tile is one base "square", with as much subdivision lines as set.
class Tile{
    constructor(node1, node2, node3, node4){
        this.nodes = [];
        // nodes are distributed wlockwise, starting from top left.
        this.nodes.push(node1);
        this.nodes.push(node2);
        this.nodes.push(node3);
        this.nodes.push(node4);
/*        
        this.node1 = node1;
        this.node2 = node2;
        this.node3 = node3;
        this.node4 = node4;
*/
    }
    
    // start and end point for limit lines (tile borders) : line 1 start limit, l1 end limit, l2 start lmiit, l2 end limit, subdivision wanted
    drawLines(a, b, c, d, sub){

        // compute the delta between each start and ends,according to tiles nodes positions and number of subdivisions.

        let dXs = (this.nodes[b].getX() - this.nodes[a].getX());
        let dYs = (this.nodes[b].getY() - this.nodes[a].getY());
        
        let dXe = (this.nodes[d].getX() - this.nodes[c].getX());
        let dYe = (this.nodes[d].getY() - this.nodes[c].getY());
      
        if(sub != 0){
            dXs /= sub;
            dYs /= sub;
            dXe /= sub;
            dYe /= sub;
        }
    
        // Set the start point, from which each line is incremented
        let startX = this.nodes[a].getX();
        let startY = this.nodes[a].getY();

        let endX = this.nodes[c].getX();
        let endY = this.nodes[c].getY();
        
        // Then walk through each point and draw lines.
        for(let i = 0; i < sub; i++){
            turtle.jump(startX, startY);
            turtle.goto(endX, endY);
            
            startX += dXs;
            startY += dYs;
            endX += dXe;
            endY += dYe;
        }
        
        // the last line of the tile is never draw, as it's the first of the following one.
        // But if this tile is the last one, we need to draw that last line.
        // Of course is subdivision is 0, we dont anything :
        if(sub == 0) return;
        
        let drawLastLine = 0
        if(this.nodes[a].line == this.nodes[b].line){
            // if a and b are on the same line, we are drawing columns
            if(this.nodes[d].column == gridSize) drawLastLine = 1
        } else {
            if(this.nodes[d].line == gridSize) drawLastLine = 1
        }
        
        if(drawLastLine){
            //the positions are already offset from the for loop above
            turtle.jump(startX, startY);
            turtle.goto(endX, endY);
        }
    }
    
    walk(){
        
        this.drawLines(0, 1, 3, 2, subdivisionX);
        this.drawLines(0, 3, 1, 2, subdivisionY);

    }
}

let tileList = [];

let nodeList = [];

// Creating all nodes according to user parameters
for(let i = 0; i < gridSize + 1; i++){
    let tileSize = size / gridSize;
    let x;
    let y;

    y = -(size/2) + tileSize * i;

    for(let j = 0; j < gridSize + 1; j++){
        x = -(size/2) + tileSize * j;
        
        nodeList.push(new Node(x, y, i, j));
    }
}

// Let's pu some randomnes in it !
for(node of nodeList){
    node.shake(move);
}

// And know, let define each tile from the nodes above.
for(let i = 0; i < gridSize; i++){
    for(let j = 0; j < gridSize; j++){
        let n = j + i * (gridSize + 1);
        tileList.push(new Tile(nodeList[n], nodeList[n+1], nodeList[n+gridSize+1+1], nodeList[n+gridSize+1]));
    }
}


function walk(i) {
    for(tile of tileList){
        tile.walk();
    }
    
    return false;
}

/*
let rand = 0;

function random(){
    let x = rand;
    x ^= x << 13;
    x ^= x >> 17;
    x ^= x << 5;
    
    return rand = x;
}

function randomSeed(s){
    return rand = s;
}

randomSeed(seed);
*/