Browse Source

some unfinished multi-scale Truchet tiling things

master
Fr3deric 6 years ago
parent
commit
6a7abb66ed
  1. 75
      truchet/truchet.html
  2. 154
      truchet/truchet.js

75
truchet/truchet.html

@ -0,0 +1,75 @@
<title>JavaScript <=> PaperScript example</title>
<code mode="text/html">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/javascript" src="truchet.js"></script>
<script type="text/javascript">
window.onload = function() {
paper.install(window);
paper.setup(document.getElementById('canvas'));
/*
var ret = draw_tile('x', new Point(200, 200), 100, false);
ret[0].scale(3);
ret[1].scale(3);
ret[1].translate(new Size(0, 400));
ret[0].fullySelected = true;
ret[1].fullySelected = true;
return;
*/
var tiles = gen_tiles(0, 3, 5);
var grp = new Group();
var dtiles = draw_tiles(tiles, new paper.Point(0, 0));
console.log(dtiles);
//dtiles[0].fillColor = 'black';
// dtiles[1].fillColor = null;
//grp.addChildren(dtiles[1]);
//grp.addChildren(dtiles[0]);
dtiles[0].fillColor = 'black';
dtiles[0].strokeColor = null;
grp.addChild(dtiles[0]); // fg
//grp.addChild(dtiles[1]); // bg
grp.addChildren(dtiles[2]); // debug
grp.translate(new Point(400, 400));
grp.scale(800);
//grp.fullySelected = true;
/*
grp.fillColor = 'black';
grp.strokeColor = null;
*/
/*
document.getElementById('download-svg').addEventListener('click', function() {
var svgdata = 'data:image/svg+xml;utf8,' + encodeURIComponent(get_svg());
var a = document.createElement('a');
a.download = 'export.svg';
a.href = svgdata;
document.body.appendChild(a);
a.click();
});
*/
}
</script>
</head>
<body>
<canvas id="canvas" style="width: 900px; height: 900px;" resize></canvas>
</body>
</html>

154
truchet/truchet.js

@ -0,0 +1,154 @@
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]];
}
}
Loading…
Cancel
Save