const tile_shapes = ['x.', '/']; //const tile_shapes = ['/']; const HLEN = 4/3 * Math.tan(Math.PI/8); function add_qcarc(path, center, steps=1) { var lastseg = path.segments[path.segments.length - 1]; var v_last = lastseg.point.subtract(center); var p_new = center.add(v_last.rotate((steps>0) ? 90 : -90)); var v_new = p_new.subtract(center); var hlen = HLEN * v_new.length; lastseg.handleOut = v_new.normalize(hlen); path.add(new Segment(p_new, v_last.normalize(hlen), null)); if(Math.abs(steps) > 1) { add_qcarc(path, center, steps - Math.sign(steps)); } } function gen_tiles(depth, min_depth, max_depth) { if(((depth >= min_depth) && (Math.random() < 0.5)) || (depth >= max_depth)) { return tile_shapes[Math.floor(Math.random() * tile_shapes.length)]; } else { return [ gen_tiles(depth + 1, min_depth, max_depth), gen_tiles(depth + 1, min_depth, max_depth), gen_tiles(depth + 1, min_depth, max_depth), gen_tiles(depth + 1, min_depth, max_depth), ]; } } function draw_tile(tile, pos, size, inverted) { console.log(pos, size); var bounds = [ new Path.Rectangle({ point: pos, size: new Size(size, size), strokeWidth: 1, strokeColor: 'black', //fillColor: inverted ? '#cccccc' : 'white', }), new Path.Line({ from: pos.add(new Point(size * 2/3, 0)), to: pos.add(new Point(size, size / 3)), strokeWidth: 1, strokeColor: 'black' }), ]; var bg = new Path.Rectangle({ point: pos, size: new Size(size, size), strokeWidth: 1, strokeColor: 'red', }); for(var x=0; x<2; x++) { for(var y=0; y<2; y++) { bg = bg.unite(new Path.Circle({ center: pos.add(new Point(x*size, y*size)), radius: size / 3, strokeWidth: 1, strokeColor: 'red', })); } } var shape = new CompoundPath({strokeWidth: 1, strokeColor: 'green'}); if(tile == 'x.') { var shape1 = new Path(); shape1.add(pos.add(new Point(size/3, 0))); add_qcarc(shape1, pos, 1); add_qcarc(shape1, pos.add(new Point(0, size/2)), -2); add_qcarc(shape1, pos.add(new Point(0, size)), 1); add_qcarc(shape1, pos.add(new Point(size/2, size)), -2); add_qcarc(shape1, pos.add(new Point(size, size)), 1); add_qcarc(shape1, pos.add(new Point(size, size/2)), -2); add_qcarc(shape1, pos.add(new Point(size, 0)), 1); add_qcarc(shape1, pos.add(new Point(size/2, 0)), -2); shape1.closed = true; shape.addChild(shape1); } else if(tile == '/') { var shape1 = new Path(); shape1.add(pos.add(new Point(size/3, 0))); add_qcarc(shape1, pos.add(new Point(size/2, 0)), 2); add_qcarc(shape1, pos.add(new Point(size, 0)), -1); add_qcarc(shape1, pos.add(new Point(size, size/2)), 2); add_qcarc(shape1, pos.add(new Point(size, 0)), 1); shape1.closed = true; shape.addChild(shape1); var shape2 = new Path(); shape2.add(pos.add(new Point(size/3, size))); add_qcarc(shape2, pos.add(new Point(size/2, size)), -2); add_qcarc(shape2, pos.add(new Point(0, size)), -1); add_qcarc(shape2, pos.add(new Point(0, size/2)), -2); add_qcarc(shape2, pos.add(new Point(0, size)), 1); shape2.closed = true; shape.addChild(shape2); } bg = bg.subtract(shape); /* if(!inverted) { return [[ shape ], [ bg ]]; } else { return [[ bg ], [ shape ]]; } */ //return ret; if(!inverted) { return [shape, bg, bounds]; } else { return [bg, shape, bounds]; } } function draw_tiles(tiles, pos, depth=1, inverted=true) { if(typeof tiles === 'string') { return draw_tile(tiles, pos, 1/Math.pow(2, depth-1), inverted); } else { var ret = null; var newsize = 1 / Math.pow(2, depth); for(var i=0; i<4; i++) { var fgbg = draw_tiles( tiles[i], pos.add(new Point(newsize * (i%2), newsize * Math.floor(i/2))), depth+1, !inverted ); if(i==0) { ret = fgbg; } else { ret[0] = ret[0].unite(fgbg[0]); ret[1] = ret[1].unite(fgbg[1]); ret[2].push.apply(ret[2], fgbg[2]); } /* if(i==0) { ret = fgbg; } else { ret[0].push.apply(ret[0], fgbg[0]); ret[1].push.apply(ret[1], fgbg[1]); } */ } var bg = ret[1].subtract(ret[0]); return [ret[0], bg, ret[2]]; } }