Skip to content

Instantly share code, notes, and snippets.

@zzandy
Last active August 29, 2015 14:21
Show Gist options
  • Save zzandy/9e74f9a349fdb37e29e5 to your computer and use it in GitHub Desktop.
Save zzandy/9e74f9a349fdb37e29e5 to your computer and use it in GitHub Desktop.
Proper pruning, no sharp turns, colors
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Hextsuro</title>
</head>
<body>
<script type="text/javascript">
var a = 100;
function rot(x, y, a) {
return [
x * Math.cos(a) - y * Math.sin(a),
x * Math.sin(a) + y * Math.cos(a)
];
}
function line(ctx, angle1, offst1, angle2, offst2, c) {
var h = a / 5;
var styles = [
{ width: a / 10, color: c },
{ width: a / 15, color: 'white' }
];
styles.forEach(function(style) {
ctx.save();
ctx.lineWidth = style.width;
ctx.strokeStyle = style.color;
ctx.beginPath();
ctx.rotate(angle1);
ctx.moveTo(offst1, -a / 2);
var p2 = rot(offst2, -h, angle2 - angle1);
var p3 = rot(offst2, -a / 2, angle2 - angle1);
ctx.bezierCurveTo(offst1, -h, p2[0], p2[1], p3[0], p3[1]);
ctx.stroke();
ctx.restore();
});
}
function addCanvas(w, h, title) {
var el = document.createElement('canvas');
el.width = w;
el.height = h;
el.title = title;
document.body.appendChild(el);
return el.getContext('2d');
}
function render(deltas, c) {
console.log(c)
var w = a / 2 / Math.sqrt(3);
var el = document.createElement('canvas');
var ctx = addCanvas(4 * w + 2, a + 2, deltas.title);
ctx.translate(1+2*w, 1+ a/2);
function angle(idx) {
return Math.floor(idx / 2) * Math.PI / 3;
}
function offset(idx){
return w * (idx % 2) - w / 2;
}
deltas.map(function (d) {
line(ctx, angle(d.i), offset(d.i), angle(d.i+d.w), offset(d.i + d.w), c);
});
ctx.beginPath();
ctx.moveTo(w, -a / 2);
ctx.lineTo(2 * w, 0);
ctx.lineTo(w, a / 2);
ctx.lineTo(-w, a / 2);
ctx.lineTo(-2 * w, 0);
ctx.lineTo(-w, -a / 2);
ctx.closePath();
ctx.stroke();
}
function Delta(w, i) {
this.w = w;
this.i = i;
}
Delta.prototype.toString = function () {
return '(' + this.w + ', ' + this.i + ')';
}
// Convert outlet map (0 1 0 1 2 2) to deltas ((2 0) (2 1) (1 4))
function toDeltas(seq) {
var k = 0;
var past = [];
var res = [];
do {
var out = seq[k];
var next = -1;
for (var i = k + 1; i < seq.length; ++i) {
if (seq[i] == out) {
res.push(new Delta(i-k, k));
past.push(out);
} else if (next == -1) {
next = i;
}
}
k = next;
} while (next != -1);
return res.sort(byIndex);
}
function printDelta(delta) { return delta.join(', ') }
function byIndex(a, b) {
return a.i - b.i;
}
function rotDelta(delta, num) {
var res = [];
for (var i = 0; i < delta.length; ++i) {
var d = delta[(delta.length + i - num) % delta.length];
var nw = d.w;
var ni = (d.i + 2*num) % 12;
if (ni + nw >= 12) {
ni = (ni + nw) % 12;
nw = 12 - nw;
}
res.push(new Delta(nw, ni));
}
return res.sort(byIndex);
}
function deltaKey(delta) {
return delta.map(function(d) { return d.w }).join(' ');
}
function iter(res, seed, num) {
var first = -1;
for (var i = 0; i < seed.length; ++i) {
if (seed[i] == -1)
{
first = i;
break;
}
}
if (first == -1) {
var delta = toDeltas(seed);
var pass = true;
if (delta.some(function (d) { return d.w == 1 || d.w==11 }))
pass = false;
else {
for (var i = 1; i < 6; ++i) {
var key = deltaKey(rotDelta(delta, i));
if (key in res) {
pass = false;
break;
}
}
}
if (pass)
res[deltaKey(delta)] = delta;
}
else {
for (var i = first + 1; i < seed.length; ++i) {
if (seed[i] == -1) {
var newseed = seed.slice(0);
newseed[first] = newseed[i] = num;
iter(res, newseed, num + 1);
}
}
}
}
var res = {};
var seed = [];
for (var i = 0; i < 12; ++i) seed.push(-1);
var start = (new Date()).getTime();
iter(res, seed, 0);
var items = [];
var n = 0;
for (var x in res) {
items.push(res[x]);
}
function calcSymmetry(deltas) {
var keys = [0, 1, 2, 3, 4, 5].map(function (i) { return deltaKey(rotDelta(deltas, i)) });
var s= keys.every(function (k, i, v) { return v[i] == v[0] })
? 0
: keys.every(function (k, i, v) { return v[i] == v[i % 2] })
? 10
: keys.every(function (k, i, v) { return v[i] == v[i % 3] })
? 20
: 100;
deltas.title = keys[0] + ' // ' + s;
return s;
}
function bySymmetry(a, b) {
return calcSymmetry(a) - calcSymmetry(b);
}
items.sort(bySymmetry).map(function (d, i, a) { render(d, 'hsl(' + (360 * i / a.length).toFixed(2) + ', 100%, 60% )') });
console.log(items.length, (((new Date()).getTime() - start)/1000).toFixed(2));
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment