Skip to content

Instantly share code, notes, and snippets.

@gfwilliams
Created May 13, 2020 08:16
Show Gist options
  • Save gfwilliams/663f7d6e280e33511881a3dfff2ee30f to your computer and use it in GitHub Desktop.
Save gfwilliams/663f7d6e280e33511881a3dfff2ee30f to your computer and use it in GitHub Desktop.
//https://emergent.unpythonic.net/software/hershey
var hershey = `12345 1JZ
12345 9MWRFRT RRYQZR[SZRY
12345 6JZNFNM RVFVM
12345 12H]SBLb RYBRb RLOZO RKUYU
12345 27H\\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX
12345 32F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT
12345 35E_\\O\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\Z\\Y
12345 8MWRHQGRFSGSIRKQL
12345 11KYVBTDRGPKOPOTPYR]T\\\`Vb
12345 11KYNBPDRGTKUPUTTYR]P\`Nb
12345 9JZRLRX RMOWU RWOMU
12345 6E_RIR[ RIR[R
12345 8NVSWRXQWRVSWSYQ[
12345 3E_IR[R
12345 6NVRVQWRXSWRV
12345 3G][BIb
12345 18H\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF
12345 5H\\NJPISFS[
12345 15H\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[
12345 16H\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW
12345 7H\\UFKTZT RUFU[
12345 18H\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW
12345 24H\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT
12345 6H\\YFO[ RKFYF
12345 30H\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF
12345 24H\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX
12345 12NVROQPRQSPRO RRVQWRXSWRV
12345 14NVROQPRQSPRO RSWRXQWRVSWSYQ[
12345 4F^ZIJRZ[
12345 6E_IO[O RIU[U
12345 4F^JIZRJ[
12345 21I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RRYQZR[SZRY
12345 56E\`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\T]Q]O\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV
12345 9I[RFJ[ RRFZ[ RMTWT
12345 24G\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[
12345 19H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV
12345 16G\\KFK[ RKFRFUGWIXKYNYSXVWXUZR[K[
12345 12H[LFL[ RLFYF RLPTP RL[Y[
12345 9HZLFL[ RLFYF RLPTP
12345 23H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS RUSZS
12345 9G]KFK[ RYFY[ RKPYP
12345 3NVRFR[
12345 11JZVFVVUYTZR[P[NZMYLVLT
12345 9G\\KFK[ RYFKT RPOY[
12345 6HYLFL[ RL[X[
12345 12F^JFJ[ RJFR[ RZFR[ RZFZ[
12345 9G]KFK[ RKFY[ RYFY[
12345 22G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF
12345 14G\\KFK[ RKFTFWGXHYJYMXOWPTQKQ
12345 25G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RSWY]
12345 17G\\KFK[ RKFTFWGXHYJYLXNWOTPKP RRPY[
12345 21H\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX
12345 6JZRFR[ RKFYF
12345 11G]KFKULXNZQ[S[VZXXYUYF
12345 6I[JFR[ RZFR[
12345 12F^HFM[ RRFM[ RRFW[ R\\FW[
12345 6H\\KFY[ RYFK[
12345 7I[JFRPR[ RZFRP
12345 9H\\YFK[ RKFYF RK[Y[
12345 12KYOBOb RPBPb ROBVB RObVb
12345 3KYKFY^
12345 12KYTBTb RUBUb RNBUB RNbUb
12345 6JZRDJR RRDZR
12345 3I[Ib[b
12345 8NVSKQMQORPSORNQO
12345 18I\\XMX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 18H[LFL[ RLPNNPMSMUNWPXSXUWXUZS[P[NZLX
12345 15I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 18I\\XFX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 18I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 9MYWFUFSGRJR[ ROMVM
12345 23I\\XMX]W\`VaTbQbOa RXPVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 11I\\MFM[ RMQPNRMUMWNXQX[
12345 9NVQFRGSFREQF RRMR[
12345 12MWRFSGTFSERF RSMS^RaPbNb
12345 9IZMFM[ RWMMW RQSX[
12345 3NVRFR[
12345 19CaGMG[ RGQJNLMOMQNRQR[ RRQUNWMZM\\N]Q][
12345 11I\\MMM[ RMQPNRMUMWNXQX[
12345 18I\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM
12345 18H[LMLb RLPNNPMSMUNWPXSXUWXUZS[P[NZLX
12345 18I\\XMXb RXPVNTMQMONMPLSLUMXOZQ[T[VZXX
12345 9KXOMO[ ROSPPRNTMWM
12345 18J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX
12345 9MYRFRWSZU[W[ ROMVM
12345 11I\\MMMWNZP[S[UZXW RXMX[
12345 6JZLMR[ RXMR[
12345 12G]JMN[ RRMN[ RRMV[ RZMV[
12345 6J[MMX[ RXMM[
12345 10JZLMR[ RXMR[P_NaLbKb
12345 9J[XMM[ RMMXM RM[X[
12345 40KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\P^Q\`RaTb
12345 3NVRBRb
12345 40KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\T^S\`RaPb
12345 24F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O
12345 35JZJFJ[K[KFLFL[M[MFNFN[O[OFPFP[Q[QFRFR[S[SFTFT[U[UFVFV[W[WFXFX[Y[YFZFZ[`.split("\n");
function getCharPoly(n,m) {
var p = [], pp=[];
var l = hershey[n].substr(10).split(" R");
l.forEach(s=>{
var x, y;
for (var i=0;i<s.length;i+=2) {
x = s.charCodeAt(i)-82;
y = s.charCodeAt(i+1)-82;
p.push(x*m, y*m);
}
pp.push(p);
p = [];
});
return pp;
}
function drawChar(n, size, xpos, ypos, pad, debug) {
var pp = getCharPoly(n,size);
pp.forEach(p=>{
var oldp = p;
var l = p.length;
for (var i=0;i<l;i+=2) {
p[i] += xpos;
p[i+1] += ypos;
}
p = p.slice(); // clone
var q = [];
var qr = [];
var closed = p[0]==p[l-2] && p[1]==p[l-1];
var x,y,d,dx,dy,ax,ay,bx,by;
if (closed) {
// closed
p[-2] = p[l-4];
p[-1] = p[l-3];
p[l] = p[2];
p[l+1] = p[3];
} else {
// open - extend ends
p[-2] = p[0] + (p[0]-p[2]);
p[-1] = p[1] + (p[1]-p[3]);
p[l] = p[l-2] + (p[l-2]-p[l-4]);
p[l+1] = p[l-1] + (p[l-1]-p[l-3]);
// add padding to ends
x = p[0];
y = p[1];
dx = x-p[-2];
dy = y-p[-1];
d = pad/Math.sqrt(dx*dx+dy*dy);
q.push(
x - (dx*d + dy*d)/1.4,
y - (dy*d - dx*d)/1.4,
x - dx*d,
y - dy*d,
x - (dx*d - dy*d)/1.4,
y - (dy*d + dx*d)/1.4
);
}
for (var i=0;i<l;i+=2) {
x = p[i];
y = p[i+1];
// dxy = vector between previous & next points
dx = p[i+2]-p[i-2];
dy = p[i+3]-p[i-1];
d = dx*dx+dy*dy;
// axy = vector from prev->this
ax = x-p[i-2];
ay = y-p[i-1];
// bxy = vector from this->next
bx = p[i+2]-x;
by = p[i+3]-y;
var z = Math.abs(ax*by - ay*bx)*2;
// fails for '3' where one edge is much longer than the other
if (z<d) z=d;
d = d*Math.sqrt(d);
// add points on both sides of the shape
q.push(
x + dy*z*pad/d, y - dx*z*pad/d
);
qr.unshift(
x - dy*z*pad/d, y + dx*z*pad/d
);
}
if (!closed) {
// add padding to ends
d = pad/Math.sqrt(dx*dx+dy*dy);
q.push(
x + (dx*d + dy*d)/1.4,
y + (dy*d - dx*d)/1.4,
x + dx*d,
y + dy*d,
x + (dx*d - dy*d)/1.4,
y + (dy*d + dx*d)/1.4
);
}
var filled = (closed&&l==10) ? qr : [].concat(q,qr);
if (debug) {
g.setColor("#7f0000");
g.fillPoly(filled);
g.setColor("#ff0000");
g.drawPoly(q);
g.setColor("#00ff00");
g.drawPoly(qr);
g.setColor(-1);
g.drawPoly(oldp);
} else
g.fillPoly(filled);
});
}
function char(n) {
g.clear();
drawChar(n, 4,60,60,7, true);
drawChar(n, 4,180,60,5);
drawChar(n, 2,60,180,4);
drawChar(n, 2,120,180,2);
drawChar(n, 1.5,160,180,2);
drawChar(n, 1,200,180,1);
}
var n = 24;
char(n);
setWatch(()=>{if (n>0)n--;char(n);},BTN1,{repeat:true})
setWatch(()=>{n++;char(n);},BTN2,{repeat:true})
console.log("USE BTN1+BTN2 to cycle through chars");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment