### Distorted Rectangles ðŸ“¦

Grid of rectangles, but with some Tortoise transforms

```// 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
const waveF = -0.3;  // min=-1, max=1, step=0.001
const waveA = 2;  // min=-3, max=13, step=0.1

const scale = 1.8;  // min=0.5, max=2, step=0.01

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 = [];
}
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);
}
```