Skip to content

Instantly share code, notes, and snippets.

Created March 13, 2018 13:45
Show Gist options
  • Save anonymous/c03066092f346bcd42dd2f3a9799fae9 to your computer and use it in GitHub Desktop.
Save anonymous/c03066092f346bcd42dd2f3a9799fae9 to your computer and use it in GitHub Desktop.
Print an 11"x8.5" page of fiduciary symbols for the Shaper Origin.
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="266.7mm" height="203.2mm" viewBox="0 0 266.7 203.2">
<g class="domino">
<rect x="0" y="0" width="43" height="12.7" rx="2.5" ry="2.5" fill="black"/>
<circle r="1.25" cx="4" cy="3.8" fill="white" />
<circle r="1.25" cx="4" cy="8.9" fill="white" />
<g class="inner-dots">
<circle r="1.25" cx="9" cy="3.8" fill="white" />
<circle r="1.25" cx="14" cy="3.8" fill="white" />
<circle r="1.25" cx="19" cy="3.8" fill="white" />
<circle r="1.25" cx="24" cy="3.8" fill="white" />
<circle r="1.25" cx="29" cy="3.8" fill="white" />
<circle r="1.25" cx="34" cy="3.8" fill="white" />
<circle r="1.25" cx="9" cy="8.9" fill="white" />
<circle r="1.25" cx="14" cy="8.9" fill="white" />
<circle r="1.25" cx="19" cy="8.9" fill="white" />
<circle r="1.25" cx="24" cy="8.9" fill="white" />
<circle r="1.25" cx="29" cy="8.9" fill="white" />
<circle r="1.25" cx="34" cy="8.9" fill="white" />
</g>
<circle r="1.25" cx="39" cy="3.8" fill="white" />
<circle r="1.25" cx="39" cy="8.9" fill="white" />
</g>
<text class="page" x="261" y="6" style="font-size: 6"></text>
<script>//<![CDATA[
/**
* Convert a number from 0..4095 to a 12-character sequence of 1's and 0's
*/
let bitStream = num => {
let bits = num.toString(2);
while (bits.length < 12) {
bits = '0' + bits;
}
return bits;
};
/**
* Hash a number from 0..4095 to a bit, using a linear feedback shift register
* The LFSR is used because the numbers we'll feed into this will always have 6
* high bits; the introduction of a shift-modulo messes with that, so each number
* will have a different value - one that's not necessarily tied to the LSB.
*/
let checkSum = num => {
let low = num & 1;
num = ((num >> 1) ^ 7185 || low << 12) & 0xFFF;
return num.toString(2).replace(/0/g, '').length & 1;
};
/**
* Test the fiduciary features of a number.
*/
let isValid = num => {
let bits = bitStream(num);
let top = bits.substr(0, 6);
let btm = bits.substr(6);
// Six interior dots must be filled
if (bits.replace(/0/g, '').length !== 6) {
return false;
}
// At least one bit must be in each row
if (top === '111111') return false;
if (top === '000000') return false;
// Must not be rotational inverse of self
let flp = parseInt(btm.split('').reverse().join('') + top.split('').reverse().join(''), 2);
if (flp === num) {
return false;
}
// Using checksum to arbitrarily decide wheter to take high or low of rotational pair
let sum = checkSum(num);
if ((sum === 1 && flp < num) || (sum === 0 && flp > num)) {
return false;
}
return true;
};
/**
* Run through the possible space
*/
let generateAll = () => {
let e = {};
for (var i = 0; i < 4096; i++) {
if (isValid(i)) {
e[i] = true;
}
}
return e;
}
// 'cept we can pre-generate them, and should.
// let all = Object.keys(generateAll()).sort(() => Math.random() > 0.5 ? 1 : -1).map(n=>parseInt(n));
let all = [2158,3920,1988,1000,3603,1260,3780,2841,3496,2358,2282,3636,3132,2412,3274,3237,1904,2744,3270,1776,2764,3752,3040,3250,2222,3724,2978,2292,3729,3684,2166,2738,3658,3282,2900,3784,1944,2792,2892,2230,3597,1650,3372,2262,3524,2481,2502,3102,984,3504,3905,3849,3157,2830,1954,3736,3370,3412,3746,2665,3425,3473,3267,1706,2842,3349,3745,2474,888,3249,3808,2673,948,2390,3906,2284,3312,1644,2268,996,2956,2506,3612,3459,3440,1490,2776,3118,2730,3777,3970,3341,2914,2652,3606,2529,1720,2110,2666,1594,1768,3912,3117,3846,2857,3696,1458,1512,2364,2897,1738,2890,3626,1692,2949,1862,3297,3158,3012,2904,3748,2476,1482,2737,3474,1436,3908,1508,3363,3241,1496,3969,1932,1866,1708,2516,3528,3860,2236,1450,3288,3621,3490,1746,2614,2713,1842,3369,3625,2418,2674,2992,1520,2858,3876,3552,2762,1212,2785,3350,1748,3228,3235,2732,3428,3651,2646,3864,3409,3880,3634,2886,3242,3221,2837,2638,2446,1734,2514,1764,3410,3850,2680,1820,3226,1740,3009,3843,2482,1492,2770,3858,1896,1400,3173,1596,3404,3342,1830,2962,3380,2980,3888,3416,1834,3465,3402,2668,3213,2420,2488,3354,3192,3298,2254,1818,2000,3304,2606,3468,2800,2761,1396,3521,2710,3225,3185,2484,940,2916,3721,3010,760,3622,3480,2206,1960,1628,3300,2968,2530,1814,2473,3101,2618,2872,1968,1848,3149,2868,1626,1394,3857,3972,1752,1874,2729,2786,3522,2508,2865,2757,3873,2961,2953,1460,2266,2920,2702,2650,2460,2838,3760,1642,2290,1992,3653,3366,3188,2142,1340,2725,1452,2788,1690,2362,2758,3398,3353,2513,3276,3633,3640,3214,1244,3126,3476,2977,3462,3162,3395,3466,3281,2885,3180,3284,2662,2454,3688,2382,2544,884,2716,1762,3718,3717,3252,3666,2532,1956,2649,3130,3244,2913,1656,3161,3609,3492,3672,3384,3125,1652,1836,980,1388,2505,1890,1272,2296,1008,3715,2860,3365,2866,1372,1986,3668,3976,2590,2617,2234,3461,4000,2394,3536,2417,3730,1484,1702,2676,3269,1938,3426,3150,3936,972,3852,3682,3129,1876,2772,3177,3874,1506,2458,3598,3665,2726,2620,2854,2898,2278,2016,1940,1844,1268,2844,2954,2769,3778,2410,3378,3792,1930,2406,2350,2172,3845,3164,3660,3722,3401,2853,3377,3984,3256,3273,3619,3174,2424,1926,3186,1868,952,2470,3605,3657,3610,2950,3432,2740,2984,3222,3595,3178,3238,2396,3356,1716,1892,2889,3681,2334,3628,2520,3654,2714,1148,1880,2170,3397,3732,1714,3016,2964,2536,3489,3024,2928,1464,3347];
let tpl = document.querySelector('g.domino');
let pageNo = document.querySelector('text.page');
tpl.parentNode.removeChild(tpl);
pageNo.parentNode.removeChild(pageNo);
let addDomino = (column, row, index) => {
let inst = tpl.cloneNode(true);
let num = all[index % all.length];
inst.setAttribute('transform', `translate(${53*column+5}, ${17.7*row})`);
[].forEach.call(inst.querySelectorAll('g.inner-dots circle'), (dot, index) => {
if (((num >> index) & 1) === 0) {
dot.parentNode.removeChild(dot);
}
});
document.documentElement.appendChild(inst);
};
let pageWidth = 5;
let pageHeight = 11;
let drawPage = page => {
while (document.documentElement.childNodes.length) {
document.documentElement.removeChild(document.documentElement.childNodes[0]);
}
for (var row = 0; row < pageHeight; row++) {
for (var column = 0; column < pageWidth; column++) {
addDomino(column, row, row*pageWidth+column + page * pageWidth * pageHeight);
}
}
let ns = document.documentElement.namespaceURI;
let ctr = pageNo.cloneNode(true);
ctr.textContent = page;
document.documentElement.appendChild(ctr);
};
let page = 0;
drawPage(page);
document.documentElement.addEventListener('keydown', e => {
if (e.key === 'PageUp') {
if (page > 0) { page -= 1; drawPage(page); }
}
if (e.key === 'PageDown') {
page += 1; drawPage(page);
}
});
//]]></script>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment