Connections on grid ✏️

Create lines from a position to random offset, but a point may be touched only few times. Its simple and random, but since everything is drawn on grid positions, it looks like there is still order.

Update; added some fun tortoise transfoms on it

Log in to post a comment.

// Forked from "Rectangles 📦" by markknol
// https://turtletoy.net/turtle/1739b05a12
const turtle = new Tortoise();
function Wave(f, a) { return p => [p[0], p[1]+Math.sin(p[0]*f)*a]; }
function Scale(s) { return p => [p[0]*s, p[1]*s]; }
function Barrel(b) { return p => { let s = (1+(p[0]**2 + p[1]**2)*b/1e4); return [p[0]*s, p[1]*s]; } }
const barrel = -0.0; // min=-2, max=1, step=0.001
turtle.addTransform(Barrel(barrel));
const waveF = -0.0;  // min=-1, max=1, step=0.001
const waveA = 0;  // min=-3, max=13, step=0.1
turtle.addTransform(Wave(waveF, waveA));

const scale = 1.0;  // min=0.5, max=2, step=0.01
turtle.addTransform(Scale(scale));

const width = 25; // min=5, max=50, step=1
const height = 25; // min=5, max=50, step=1

const size = 200 - 20;

let grid;

// The walk function will be called until it returns false.
function walk(i) {
    if (grid == null) grid = new LazyGrid(width,height);
    const x1 = (Math.random() * width) | 0;
    const y1 = (Math.random() * height) | 0;
    
    const movement = 2; // min=1, max=5, step=1
    const amount1 = (1 + Math.random() * movement) | 0;
    const x2 = x1 + (Math.random() > 0.5 ? -amount1 : amount1);
    const amount2 = (1 + Math.random() * movement) | 0;
    const y2 = y1 + (Math.random() > 0.5 ? -amount2 : amount2);
    
    if (x2 < 0 || y2 < 0 || x2 >= width || y2 >= height) return true;
    
    if (x2 !== x1 && y1 !== y2) {
        const g1 = grid.get(x1,y1);
        const g2 = grid.get(x2,y2);
        const connections = 2; // min=1, max=10, step=1
        if (g1 < connections && g2 < connections) {
            grid.set(x1,y1, g1 + 1);
            grid.set(x2,y2, g2 + 1);
            
            turtle.jump(-size/2 + x1 * size/(width-1), -size/2 + y1 * size/(height-1));
            turtle.goto(-size/2 + x2 * size/(width-1), -size/2 + y2 * size/(height-1));
        }
    }
    
    return i<width*height*10;
}

class LazyGrid {
    constructor(width, height) {
        const data = {}
        this._data = data;
        
        for (let y=0; y<height; y++) {
            for (let x=0; x<width; x++) {
                if (!data[x]) data[x] = {};
                 if (!data[x][y]) data[x][y] = 0;
            }
        }
    }
    set(x,y, value) {
        this._data[x][y] = value;
    }
    get(x,y) {
        return this._data[x][y];
    }
}


////////////////////////////////////////////////////////////////
// Tortoise utility code (Minimal Turtle and Transforms)
// https://turtletoy.net/turtle/102cbd7c4d
////////////////////////////////////////////////////////////////

function Tortoise(x, y) {
    class Tortoise extends Turtle {
        constructor(x, y) {
            super(x, y);
            this.ps = Array.isArray(x) ? [...x] : [x || 0, y || 0];
            this.transforms = [];
        }
        addTransform(t) {
            this.transforms.push(t);
            this.jump(this.ps);
            return this;
        }
        applyTransforms(p) {
            if (!this.transforms) return p;
            let pt = [...p];
            this.transforms.map(t => { pt = t(pt); });
            return pt;
        }
        goto(x, y) {
            const p = Array.isArray(x) ? [...x] : [x, y];
            const pt = this.applyTransforms(p);
            if (this.isdown() && (this.pt[0]-pt[0])**2 + (this.pt[1]-pt[1])**2 > 4) {
               this.goto((this.ps[0]+p[0])/2, (this.ps[1]+p[1])/2);
               this.goto(p);
            } else {
                super.goto(pt);
                this.ps = p;
                this.pt = pt;
            }
        }
        position() { return this.ps; }
    }
    return new Tortoise(x,y);
}