Skip to content

Instantly share code, notes, and snippets.

@Fordi
Forked from anonymous/shaper-dots.svg
Last active September 24, 2023 00:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fordi/97087480faf990e29fc5985fc02ce2f6 to your computer and use it in GitHub Desktop.
Save Fordi/97087480faf990e29fc5985fc02ce2f6 to your computer and use it in GitHub Desktop.
Print an 11"x8.5" page of fiducial markers for the Shaper Origin. Download this SVG and open it in your browser to use it. PageUp/PageDown to change pages. Demo: http://fordi.org/shaper-dots.svg
/**
* Returns true if number adheres to shaper domino rules:
* - 12 bits (0..4095)
* - Exactly 6 bits are '1'
* - bits 0..5 contain at least one '1'
* - bits 6..B contain at least one '1'
* - Must not be rotational inverse of self
* - No number in the list matches the bit-reverse of another number in the list.
* @param {number} num
* @returns {boolean} if adherent
**/
const isValidShaperNumber = num => {
// 12 bits (0..4095)
if (num < 0 || num > 4095) return false;
const bits = num.toString(2).padStart(12, 0);
const top = bits.substr(0, 6);
const btm = bits.substr(6);
// Exactly 6 bits are '1'
if (bits.split('').filter(b => b === '1').length !== 6) return false;
// At least one bit must be in each row
if (top === '000000' || btm === '000000') return false;
// Must not be rotational inverse of self
let flp = parseInt(bits.split('').reverse().join(''), 2);
if (flp === num) return false;
// No number in the list matches the bit-reverse of another number
if (flp < num) return false;
return true;
};
const generateList = (min, max, rule) => {
let e = [];
for (let num = min; num < max; num++) rule(num) && e.push(num);
return e;
};
console.log(JSON.stringify(generateList(0, 4095, isValidShaperNumber)));
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
import React from 'react';
/**
* Convert a number into a 12-digit binary number string
*/
const dots = num => {
const n = num.toString(2).padStart(12, 0).split('').slice(0, 12);
return `1${n.substr(0, 6)}11${n.substr(6)}1`;
};
/**
* See generateShaperNumbers.js to see how this is generated.
*/
const all = [
95,111,119,123,125,126,159,175,183,187,189,190,207,215,219,221,222,231,235,237,
238,243,245,246,249,250,252,287,303,311,315,317,318,335,343,347,349,350,359,363,
365,366,371,373,374,377,378,380,399,407,411,413,414,423,427,429,430,435,437,438,
441,442,444,455,459,461,462,467,469,470,473,474,476,483,485,486,489,490,492,497,
498,500,543,559,567,571,573,574,591,599,603,605,606,615,619,621,622,627,629,630,
633,634,636,655,663,667,669,670,679,683,685,686,691,693,694,697,698,700,711,715,
717,718,723,725,726,729,730,732,739,741,742,745,746,748,753,754,783,791,795,797,
798,807,811,813,814,819,821,822,825,826,828,839,843,845,846,851,853,854,857,858,
860,867,869,870,873,874,881,882,903,907,909,910,915,917,918,921,922,931,933,934,
937,938,945,946,963,965,966,969,970,977,978,993,994,1055,1071,1079,1083,1085,
1086,1103,1111,1115,1117,1118,1127,1131,1133,1134,1139,1141,1142,1145,1146,1167,
1175,1179,1181,1182,1191,1195,1197,1198,1203,1205,1206,1209,1210,1223,1227,1229,
1230,1235,1237,1238,1241,1242,1251,1253,1254,1257,1258,1265,1295,1303,1307,1309,
1310,1319,1323,1325,1326,1331,1333,1334,1337,1338,1351,1355,1357,1358,1363,1365,
1366,1369,1370,1379,1381,1382,1385,1393,1415,1419,1421,1422,1427,1429,1430,1433,
1443,1445,1446,1449,1457,1475,1477,1478,1481,1489,1505,1551,1559,1563,1565,1566,
1575,1579,1581,1582,1587,1589,1590,1593,1607,1611,1613,1614,1619,1621,1622,1625,
1635,1637,1641,1649,1671,1675,1677,1678,1683,1685,1689,1699,1701,1705,1713,1731,
1733,1737,1745,1761,1799,1803,1805,1811,1813,1817,1827,1829,1833,1841,1859,1861,
1865,1873,1889,1923,1925,1929,1937,1953,1985,2079,2095,2103,2107,2109,2127,2135,
2139,2141,2151,2155,2157,2163,2165,2169,2191,2199,2203,2205,2215,2219,2221,2227,
2229,2233,2247,2251,2253,2259,2261,2265,2275,2277,2281,2319,2327,2331,2333,2343,
2347,2349,2355,2357,2361,2375,2379,2381,2387,2389,2393,2403,2405,2439,2443,2445,
2451,2453,2467,2469,2499,2501,2575,2583,2587,2589,2599,2603,2605,2611,2613,2631,
2635,2637,2643,2645,2659,2695,2699,2701,2707,2723,2755,2823,2827,2835,2851,2883,
2947,3087,3095,3099,3111,3115,3123,3143,3147,3155,3207,3211,3335
];
/** Dot.js */
// Needs to be precise
const dotSize = [1.27, 1.27];
const dotSpace = [5.059, 5.05];
const dotMargin = [3.7995, 3.819];
const Dot = ({ index }) => (
<ellipse
fill="white"
rx={dotSize[0]}
ry={dotSize[1]}
cx={(index % 8) * dotSpace[0] + dotMargin[0]}
cy={floor(index / 8) * dotSpace[1] + dotMargin[1]}
/>
);
/** Domino.js */
// Needs to be precise
const dominoSize = [42.995, 12.672];
// Not so much
const dominoSpace = [10, 10];
export default ({ number }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width={dominoSize[0] + dominoSpace[0]}
height={dominoSize[1] + dominoSpace[1]}
viewBox={`0 0 ${dominoSize[0] + dominoSpace[0]} ${dominoSize[1] + dominoSpace[1]}`}>
<g class="domino">
<rect
x={dominoSpace[0] / 2}
y={dominoSpace[1] / 2}
width={dominoSize[0]}
height={dominoSize[1]}
rx="2.5"
ry="2.5"
fill="black"
/>
{dots(all[number % all.length]).map((bit, index) => (
bit !== '0' && <Dot key={bit + index} index={index} />
))}
</g>
</svg>
);
@buschsom
Copy link

buschsom commented Sep 25, 2020

Hi,

Impressed by your work :)
Made a 100x100mm square using the internal design feature in the Shaper Origin:

  1. Using original domino's resultet in exact size
  2. Using the 43x12.7 domino's printed out from this site, resulted in 98x99mm. So that means it should be 43x12,82 (something like 1.693x0.505 inches). and btw, if the 44 is used instead of 43, it results in 1 mm wider domino, and still 1 mm too small domino.
    Seem like the dimentions of the domino's are both determinators.
    Can see that 42.995 and 2.672 is used by Heusserurs.

@Fordi
Copy link
Author

Fordi commented Sep 25, 2020

Hm. There's more than just the size of the dominoes embedded in that. There's also the spacing between.

The 98x99 mm metric is useful, though. I can adjust the page size without modifying other code, I think. I've updated the gist. Please validate with that.

@Fordi
Copy link
Author

Fordi commented Sep 25, 2020

Do you have a link to 'Heusserurs'?

@buschsom
Copy link

buschsom commented Sep 25, 2020 via email

@buschsom
Copy link

Hi,

I did test and got the same results using https://fordi.org/shaper-dots.svg. I looked at the web page source, and can see that the recent changes you made, is not reflected in https://fordi.org/shaper-dots.svg. Could you eventually setup a "https://fordi.org/TESTING-shaper-dots.svg" webpage?

@Fordi
Copy link
Author

Fordi commented Sep 30, 2020

I'd rather not put testing in prod. Can you just download the SVG file and drag it to your browser?

@Fordi
Copy link
Author

Fordi commented Sep 30, 2020

Nevermind. I've updated the gist's SVG and JSX to match what heusserurs is doing, and updated https://fordi.org/shaper-dots.svg

@buschsom
Copy link

buschsom commented Oct 4, 2020

THX :)
Test: as usual 100x100 mm square, output 99x99mm. Printed on A4 Landscape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment