Distorted Rectangles 📦

Grid of rectangles, but with some Tortoise transforms

twitter.com/mknol

Log in to post a comment.

// Forked from "Rectangles 📦" by markknol
// https://turtletoy.net/turtle/1739b05a12
const turtle = new Tortoise();
function Translate(x,y) { return p => [p[0]+x, p[1]+y]; }
function Wave(f, a) { return p => [p[0], p[1]+Math.sin(p[0]*f)*a]; }
function Rotate(a) { return p => [p[0]*Math.cos(a)+p[1]*Math.sin(a), p[1]*Math.cos(a)-p[0]*Math.sin(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.75; // min=-2, max=1, step=0.001
turtle.addTransform(Barrel(barrel));
const waveF = -0.3;  // min=-1, max=1, step=0.001
const waveA = 2;  // min=-3, max=13, step=0.1
turtle.addTransform(Wave(waveF, waveA));

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

const w = 150; // min=1, max=400, step=1
const h = 150; // min=1, max=400, step=1

const gridx = 20; // min=1, max=40, step=1
const gridy = 15; // min=1, max=40, step=1

const t = 4; // min=1, max=40, step=1

const itemw = w / gridx;
const itemh = h / gridy;


const w2 = w * 0.5;
const h2 = h * 0.5;
const itemw2 = itemw * .5;
const itemh2 = itemh * .5;


function walk(i) {
    const x = i % gridx;
    const y = (i / gridx) | 0;
    if ((x + y) % 2 == 0) {
        const x2 = -w2 + x * itemw;
        const y2 = -w2 + y * itemh;
        infiniteRect(x2, y2, itemw, itemh);
    } else {
        for (let i = 0; i < 4; i++) {
            const x2 = -w2 + x * itemw + (i % 2) * itemw2;
            const y2 = -w2 + y * itemh + ((i / 2) | 0) * itemh2;
            infiniteRect(x2, y2, itemw2, itemh2);
        }
    }
    return i + 1 < gridx * gridy;
}

function infiniteRect(x, y, w, h) {
	if (w <= 2 || h <= 2) return;
	//let t = 3;
	for (let i = 0; i < t; i++) {
		rect(x + i , y + i , w - i * 2, h - i * 2);
	}
	let i = t + 1;
    infiniteRect(x + i, y+i , w - i * 2, h - i * 2);
}

function rect(x, y, w, h) {
	turtle.penup();
    turtle.goto(x, y);
	turtle.pendown();
	turtle.goto(x + w, y);
	turtle.goto(x + w, y + h);
	turtle.goto(x, y + h);
	turtle.goto(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);
}