Didn't quite work out the way I wanted, but it's something.
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(1); let size = 5; // min=1 max=100 step=0.1 let W=15; // min = 1 max = 100 step=1 let H=W; let symetry_mode = 2; // min=1 max=2 step=1 (rot6, rot6+mirror) // Global code will be evaluated once. const turtle = new Turtle(); class V2 { constructor(x, y) { this.x = x; this.y = y; } add(b) { return new V2(this.x + b.x, this.y + b.y); } sub(b) { return new V2(this.x - b.x, this.y - b.y); } mul(b) { return new V2(this.x * b, this.y * b); } flipx() { return new V2(-this.x, this.y); } flipy() { return new V2(this.x, -this.y); } rotDeg(deg) { const a = deg*Math.PI/180; const s = Math.sin(a); const c = Math.cos(a); return new V2(this.x*c-this.y*s, this.x*s+this.y*c); } asPair() { return [this.x, this.y]; } outp() { return this.flipy().mul(size).asPair(); } } const DVX = new V2(Math.sqrt(3), 0); const DVY = new V2(Math.sqrt(3)/2, -3/2); function hexToPixel(hexpos) { return DVX.mul(hexpos.x).add(DVY.mul(hexpos.y)); } function hexRotate(hp, n=1) { for (let i=0; i<n; i++) { let q=hp.x, r=hp.y; let s = -q-r; hp = new V2(-r, -s); } return hp; } let corners=[] for (let i=0; i<6; i++) { let a = (30+60*i)/180*Math.PI; corners.push(new V2(Math.cos(a), Math.sin(a))); } const DHEX = [ new V2(1, 0), new V2(1, -1), new V2(0, -1), new V2(-1, 0), new V2(-1, 1), new V2(0, 1) ]; function side(p1, p2) { return corners[p1].mul(2).add(corners[p2]).mul(1/3); } let loops = [ [side(0, 5), new V2(Math.sqrt(3)/2-1/(Math.sqrt(3)*6), 0), side(5, 0)], [side(0, 5), (corners[0].add(corners[5]).add(corners[1])).mul(1/3), side(0, 1)], [side(0, 5), side(1, 2)], [side(0, 5), side(2, 3)], [side(0, 5), side(3, 4)], [side(0, 5), side(4, 5).add(corners[0].sub(corners[5]).mul(2/3)), side(4, 5)], ]; function randInt(maxExclusive) { return Math.min(Math.floor(Math.random()*maxExclusive), maxExclusive-1); } //console.log(corners); //console.log(loops); class PlacedTile { constructor(tile, dir) { this.tile = tile; this.dir = dir % 6; } drawAt(pos) { let pv2 = hexToPixel(pos); let p = []; for (let i=0; i<6; i++) { //if (i != 2) continue; p = []; let d = (i+this.dir)%6; let g0 = this.tile.connections[d]; let d2 = (d+1)%6; if (g0 > 0) { while (this.tile.connections[d2] != g0) { d2 = (d2+1)%6; } } else { d2 = d; } // console.log(d2); let k = (d2 - d + 6) % 6; //console.log(loops[k]); loops[k].forEach((v) => { p.push(v.rotDeg(60 * i)); }); turtle.jump(pv2.add(p[0]).outp()); for (let i=1; i<p.length; i++) { turtle.goto(pv2.add(p[i]).outp()); } } } mirror1() { let connections = this.tile.connections.slice(0); //connections.push(this.tile.connections[0]); connections.reverse(); let tile2 = new Tile(connections, this.tile.symetry); return tile2.place(6-this.dir); } } class Tile { constructor(connections, symetry) { this.connections = connections; this.symetry = symetry; } isSymetric(dir, rot=0) { dir += rot; return this.symetry[dir % 3] > 0; } fullSymetry() { return this.symetry[0]+this.symetry[1]+this.symetry[2] == 3; } angledSymetry() { return this.symetry[3] > 0; } place(dir) { return new PlacedTile(this, dir); } } const tiles = [ new Tile([1,1,1,1,1,1], [1, 1, 1, 1]), new Tile([0,0,0,0,0,0], [1, 1, 1, 1]), new Tile([1,1,2,2,3,3], [0, 0, 0, 1]), // othersymb new Tile([1,2,2,1,3,3], [1, 0, 0, 0]) , new Tile([1,0,0,1,0,0], [1, 0, 0, 0]) , new Tile([1,1,0,1,0,1], [1, 0, 0, 0]) , new Tile([0,1,1,0,2,2], [1, 0, 0, 0]), new Tile([0,1,1,0,1,1], [1, 0, 0, 0]), new Tile([1,2,2,1,0,1], [0, 0, 0, 0]), new Tile([1,1,1,0,0,1], [0, 0, 0, 1]), new Tile([1,1,2,3,3,2], [0, 0, 0, 1]), ]; //turtle.penup(); //turtle.goto(0, 0); let data=[]; turtle.pendown(); for (let y=0; y<H; y++) { let line = []; for (let x=0; x<W; x++) { if (symetry_mode == 2 && x < y) { let v = data[x][y]; line.push(v.mirror1()); continue; } let candidates = []; tiles.forEach((t) => { let good = true; if ((x == 0 && y == 0)) { good = t.fullSymetry(); } else if (x == y) { good = t.angledSymetry(); } else if (y == 0) { good = t.isSymetric(0); } if (good) { candidates.push(t); } }); if (x+y > W) { candidates = [tiles[1]]; } let rot = 0; let tile = candidates[randInt(candidates.length)]; if (y == 0 && x > 0) { rot = randInt(2)*3; } else if (x == y) { rot = 1+randInt(2)*3; }else { rot = randInt(6); } let pt = tile.place(rot); line.push(pt); } data.push(line); } for (let x=0; x<W; x++) { for (let y=0; y<H; y++) { let t = data[y][x]; let maxr = (x+y == 0) ? 1 : 6; if (y > 0 && x==0) { continue; } for (let r=0; r<maxr; r++) { let p2 = hexRotate(new V2(x, y), r); let d2 = data[y][x].tile.place((t.dir+r+6)%6); d2.drawAt(p2); } } } /*for (let x=0; x<W; x++) { let line = []; for (let y=0; y<H; y++) { let t = tiles[randInt(tiles.length)].place(randInt(6)).drawAt(new V2(x, y)); } }*/ // The walk function will be called until it returns false. function walk(i) { return false; //turtle.forward(5); //turtle.right(144); //return i < 4; }