The Symbol for Biological Hazard with dimensions as defined in archive.org/stream/f…t#page/n849/mode/1up
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax Canvas.setpenopacity(1); const scale = 3; //min=.5, max=3.6, step=0.1 const showHelperLines = 1; //min=0, max=1, step=1 const a = 1 * scale; const b = 3.5 * scale; const c = 4 * scale; const d = 6 * scale; const e = 11 * scale; const f = 15 * scale; const g = 21 * scale; const h = 30 * scale; // Global code will be evaluated once. const text = new Text(); const turtle = new Turtle(); turtle.radians(); // The walk function will be called until it returns false. function walk(i) { let outerAngles = getIntersectionAnglesForCircles(f, e - a + b, (g / 2) - a); let halfA = outerAngles[0] / 2; let halfAOuter = outerAngles[1] / 2; //center circle outside turtle.jump(0, e - a + b); turtle.seth(Math.PI); turtle.penup(); turtle.circle(e - a + b, Math.PI - halfA); turtle.pendown(); for(let j = 0; j < 3; j++) { turtle.circle(e - a + b, 2 * halfA); turtle.penup(); turtle.circle(e - a + b, (Math.PI * 2 / 3) - 2 * halfA); turtle.pendown(); } let innerAngles = getIntersectionAnglesForCircles(f, e - a, (g / 2) - a); let halfB = innerAngles[0] / 2; let halfBOuter = innerAngles[1] / 2; //center circle inside turtle.jump(0, e - a); turtle.seth(Math.PI); turtle.penup(); turtle.circle(e - a, Math.PI - halfB); turtle.pendown(); for(let j = 0; j < 3; j++) { turtle.circle(e - a, 2 * halfB); turtle.penup(); turtle.circle(e - a, (Math.PI * 2 / 3) - 2 * halfB); turtle.pendown(); } let innerCircleHooks = []; //inner circle (start down, go clockwise) turtle.jump(0, d / 2); turtle.seth(Math.PI); let dgate = 2*Math.asin(a/d); let dcov = (2 * Math.PI / 3) - dgate; turtle.penup(); turtle.circle(d / 2, dcov / 2); turtle.circle(d / 2, dgate); turtle.pendown(); for(let j = 0; j < 3; j++) { innerCircleHooks.push(turtle.pos()); turtle.circle(d / 2, dcov); innerCircleHooks.push(turtle.pos()); turtle.penup(); turtle.circle(d / 2, dgate); turtle.pendown(); } //turtle.circle(d / 2, 2* Math.PI); let innerThreeCircles = []; let innerThreeCirclesOut = []; let outerThreeCirclesOut = []; let dst = Math.sin(Math.PI / 3) * e * 2; //let bigOneStart = Math.acos((dst / 2) / (h / 2)); //let bigOneStart = getCircleAngle(dst, h / 2, h / 2) * 1.077; let oAngles = getIntersectionAnglesForCircles(dst, h / 2, h / 2); let bigOneStart = oAngles[0] / 5; for(let j = 0; j < 3; j++) { //big one turtle.jump(-Math.sin(j/3 * 2 * Math.PI) * (-e + (h / 2)), Math.cos(j/3 * 2 * Math.PI) * (-e + (h / 2))); let ogate = 2*Math.asin(c / h); turtle.seth(Math.PI + (j/3 * 2 * Math.PI)); turtle.penup(); turtle.circle(h / 2, bigOneStart + (Math.PI/3)); turtle.pendown(); turtle.circle(h / 2, Math.PI - (ogate / 2) - (bigOneStart + (Math.PI/3))); turtle.penup(); outerThreeCirclesOut.push(turtle.pos()); turtle.circle(h / 2, ogate); outerThreeCirclesOut.push(turtle.pos()); turtle.pendown(); turtle.circle(h / 2, Math.PI - (ogate / 2) - (bigOneStart + (Math.PI/3))); //small one turtle.jump(Math.sin(j/3 * 2 * Math.PI) * (f - (g / 2)), -Math.cos(j/3 * 2 * Math.PI) * (f - (g / 2))); turtle.seth(Math.PI + (j/3 * 2 * Math.PI)); let ismgate = 2*Math.asin(a/g); let ilgate = 2*Math.asin(c/g); let ismcov = ((2 * Math.PI) - ismgate - ilgate) / 2; turtle.penup(); turtle.circle(g / 2, ismgate / 2); innerThreeCircles.push(turtle.pos()); turtle.pendown(); turtle.circle(g / 2, ismcov); turtle.penup(); innerThreeCirclesOut.push(turtle.pos()); turtle.circle(g / 2, ilgate); innerThreeCirclesOut.push(turtle.pos()); turtle.pendown(); turtle.circle(g / 2, ismcov); innerThreeCircles.push(turtle.pos()); // turtle.circle(g / 2, 2 * Math.PI); turtle.jump(Math.sin(j/3 * 2 * Math.PI) * (f - (g / 2) + a), -Math.cos(j/3 * 2 * Math.PI) * (f - (g / 2) + a)); turtle.seth(Math.PI + (j/3 * 2 * Math.PI)); turtle.penup(); turtle.circle((g / 2) - a, -halfAOuter); turtle.pendown(); turtle.circle((g / 2) - a, halfAOuter - halfBOuter); turtle.penup(); turtle.circle((g / 2) - a, 2 * halfBOuter); turtle.pendown(); turtle.circle((g / 2) - a, halfAOuter - halfBOuter); } let helperA = []; for(let j = 0; j < 6; j++) { turtle.jump(innerCircleHooks[j]); let t = turtle.pos(); turtle.goto(innerThreeCircles[(j + 5) % 6]); if(j == 3 || j == 4) { helperA.push([(turtle.pos()[0] + t[0]) / 2, (turtle.pos()[1] + t[1]) / 2]); } turtle.jump(innerThreeCirclesOut[j]); turtle.goto(outerThreeCirclesOut[j]); } if(showHelperLines == 0) { turtle.jump(-35, 90); turtle.seth(0); text.print(turtle, '- Biohazard -', .3); } if(showHelperLines == 1) { turtle.seth(0);//Math.PI*3/2); turtle.jump(-75,83); text.print(turtle, 'Dimension A B C D E F G H', .25) turtle.jump(-51,93); text.print(turtle, 'Units 1 3.5 4 6 11 15 21 30', .2) //axis dashedLine(-95, 0, 95, 0, [1,2,3,2]); dashedLine(0, -f*1.95, 0, -f*1.9, [1,2,3,2]); dashedLine(0, -f*1.75, 0, -f*1.6, [1,2,3,2]); dashedLine(0, -f*1.43, 0, -d*1.3, [1,2,3,2]); dashedLine(0, -d*1, 0, 75, [1,2,3,2]); turtle.jump(d * 1.2, -e*.4); turtle.seth(0); text.print(turtle, 'Base unit', .15) //a dashedLine(0, -e + a, 75, -e + a, [1,1]); turtle.jump(e*1.1, -e*.6); turtle.seth(0); text.print(turtle, 'A', .2) lineArrow((e*1.1) + 2.2, -e, (e*1.1) + 2.2, -e-a-a-a, 3, Math.PI/6, 1) lineArrow((e*1.1) + 2.2, -e+a, (e*1.1) + 2.2, -e+a+a+a, 3, Math.PI/6, 1) turtle.seth(0); turtle.jump(d*.9, -e*.25); text.print(turtle, 'A', .2) lineArrow(helperA[0][0]+5.5, helperA[0][1]-(5.5*Math.tan(Math.PI / 3)), helperA[0][0],helperA[0][1] , 3, Math.PI/6, 2) lineArrow(helperA[1][0]-5.5, helperA[1][1]+(5.5*Math.tan(Math.PI / 3)), helperA[1][0], helperA[1][1] , 3, Math.PI/6, 2) turtle.seth(0); turtle.jump(d*1.25, e*.8); text.print(turtle, 'A', .2) let rrrr = e - a + (b/2); let halfAngles = getIntersectionAnglesForCircles(f, rrrr, (g / 2) - a); turtle.jump(0, -rrrr); turtle.penup(); turtle.circle(rrrr, (2 * Math.PI / 3) + (halfAngles[0] / 2)) turtle.pendown(); arrowHead(turtle, 3, Math.PI / 6); turtle.circle(rrrr, -.3); turtle.penup(); turtle.circle(rrrr, .3 + (a / rrrr)); turtle.pendown(); turtle.left(Math.PI); arrowHead(turtle, 3, Math.PI / 6); turtle.left(Math.PI); turtle.circle(rrrr, .25); //b dashedLine(0, -e + a - b, 75, -e + a - b, [1,1]); turtle.jump(f*1.2, -e*1.05); turtle.seth(0); text.print(turtle, 'B', .2) lineArrow((f*1.2) + 2.2, -e+a-b, (f*1.2) + 2.2, -e+a-b-b, 3, Math.PI/6, 1) lineArrow((f*1.2) + 2.2, -e+a, (f*1.2) + 2.2, -e+a+a+a, 3, Math.PI/6, 1) //c dashedLine(-c/2, -f*1.4, -c/2, -f*1.7, [1,1]) dashedLine(c/2, -f*1.4, c/2, -f*1.7, [1,1]) turtle.jump(-2.4, -f*1.50); turtle.seth(0); text.print(turtle, 'C', .2) lineArrow(-4, -f*1.5, -c/2, -f*1.5, 3, Math.PI/6, 2) lineArrow(4, -f*1.5, c/2, -f*1.5, 3, Math.PI/6, 2) //d dashedLine(-d/2, -d*1.3, -d/2, 0, [1,1]) dashedLine(d/2, -d*1.3, d/2, 0, [1,1]) turtle.jump(-2.4, -d*1.1); turtle.seth(0); text.print(turtle, 'D', .2) lineArrow(-4, -d*1.1, -d/2, -d*1.1, 3, Math.PI/6, 2) lineArrow(4, -d*1.1, d/2, -d*1.1, 3, Math.PI/6, 2) //e dashedLine(-5, -e, f*1.15, -e, [3,1,1,1]); dashedLine(f*1.35, -e, 85, -e, [3,1,1,1]); turtle.jump(f*1.75, -e/2); turtle.seth(0); text.print(turtle, 'E', .2) lineArrow((f*1.75) + 2.2, (-e/2) - 4, (f*1.75) + 2.2, -e, 3, Math.PI/6, 2) lineArrow((f*1.75) + 2.2, (-e/2) + 3, (f*1.75) + 2.2, 0, 3, Math.PI/6, 2) //f dashedLine(-5, -f, 95, -f, [3,1,1,1]); turtle.jump(f*2, -f/2); turtle.seth(0); text.print(turtle, 'F', .2) lineArrow((f*2) + 2.2, (-f/2) - 4, (f*2) + 2.2, -f, 3, Math.PI/6, 2) lineArrow((f*2) + 2.2, (-f/2) + 3, (f*2) + 2.2, 0, 3, Math.PI/6, 2) //g dashedLine(-g/2, -h/2.5, -g/2, -85, [1,1]) dashedLine(g/2, -h/2.5, g/2, -85, [1,1]) turtle.jump(-2.4, -f*1.82); turtle.seth(0); text.print(turtle, 'G', .2) lineArrow(-4, -f*1.82, -g/2, -f*1.82, 3, Math.PI/6, 2) lineArrow(4, -f*1.82, g/2, -f*1.82, 3, Math.PI/6, 2) //h dashedLine(-h/2, -h/2.5, -h/2, -95, [1,1]) dashedLine(h/2, -h/2.5, h/2, -95, [1,1]) turtle.jump(-2.4, -f*2.03); turtle.seth(0); text.print(turtle, 'H', .2) lineArrow(-4, -f*2.03, -h/2, -f*2.03, 3, Math.PI/6, 2) lineArrow(4, -f*2.03, h/2, -f*2.03, 3, Math.PI/6, 2) //210 deg let rrr = (f*1.1)/Math.cos(Math.PI / 6); turtle.seth((Math.PI/6)+(Math.PI/2)); turtle.jump(f*1.1, Math.tan(Math.PI / 6) * f*1.1); arrowHead(turtle, 3, Math.PI / 6); turtle.circle(rrr, -Math.PI/12); turtle.seth(0); turtle.jump(turtle.pos()[0] - (a/2), turtle.pos()[1] + (3*a)); text.print(turtle, '210', .15); text.print(turtle, ' o', .10); dashedLine(0, 0, 95, Math.tan(Math.PI / 6) * 95, [4,2]); //330 deg turtle.seth((Math.PI/6)+(Math.PI/2)); turtle.jump(f*1.1, Math.tan(Math.PI / 6) * f*1.1); turtle.pu(); turtle.circle(rrr, Math.PI/3*2); turtle.pd(); arrowHead(turtle, 3, Math.PI / 6); turtle.circle(rrr, -Math.PI/12); turtle.seth(0); turtle.jump(turtle.pos()[0] - (1.5*a), turtle.pos()[1] - (2.5*a)); text.print(turtle, '330', .15); text.print(turtle, ' o', .10); dashedLine(0, 0, -95, Math.tan(Math.PI / 6) * 95, [4,2]); //90 deg turtle.seth((Math.PI/6)+(Math.PI/2)); turtle.jump(f*1.1, Math.tan(Math.PI / 6) * f*1.1); turtle.pu(); turtle.circle(rrr, Math.PI/3*4); turtle.pd(); arrowHead(turtle, 3, Math.PI / 6); turtle.circle(rrr, -Math.PI/12); turtle.seth(0); turtle.jump(turtle.pos()[0] + a, turtle.pos()[1] + a); text.print(turtle, '90', .15); text.print(turtle, ' o', .10); } return false; } function getIntersectionAnglesForCircles(d, r1, r2) { //Area of triangle using Heron's https://nl.wikipedia.org/wiki/Formule_van_Heron let s = (d + r1 + r2) / 2; let O = Math.sqrt(s * (s - d) * (s - r1) * (s - r2)); //Area of kite using https://nl.wikipedia.org/wiki/Vlieger_(meetkunde) //let A = d * BD / 2 //4 * O / d = BD; let BD = (4*O) / d; return [ Math.asin((BD / 2) / r1) * 2, Math.asin((BD / 2) / r2) * 2 ] } function arrowHead(turtle, arrowSize, arrowAngle) { if(arrowSize === null) { arrowSize = 3; } if(arrowAngle === null) { arrowAngle = Math.PI / 6; } let h = turtle.heading(); let p = turtle.pos(); turtle.right(Math.PI - arrowAngle); turtle.forward(arrowSize); turtle.jump(p); turtle.right(2 * arrowAngle); turtle.forward(arrowSize); turtle.jump(p); turtle.seth(h); } function lineArrow(x1, y1, x2, y2, arrowSize, arrowAngle, heads = 3) { let heading = y2 > y1? Math.PI / 2: Math.PI / 2 * 3; if(x1 != x2) { heading = (x2-x1 < 0? Math.PI: 0) + Math.atan((y2 - y1) / (x2 - x1)); } arrow(x1, y1, heading, Math.sqrt((x2-x1)**2 + (y2-y1)**2), null, null, arrowSize, arrowAngle, heads); } function arrow(x1, y1, heading, length, radius, extent, arrowSize = 3, arrowAngle = null, heads = 3) { let isArc = length === null; if(arrowAngle === null) { arrowAngle = Math.PI / 6; } turtle.jump(x1, y1); turtle.setheading(heading); if((heads & 1) == 1) { turtle.left(arrowAngle); turtle.forward(arrowSize); turtle.penup(); turtle.backward(arrowSize); turtle.pendown(); turtle.right(2*arrowAngle); turtle.forward(arrowSize); turtle.penup(); turtle.backward(arrowSize); turtle.pendown(); turtle.setheading(heading); } if(isArc) { turtle.circle(radius, extent); } else { turtle.forward(length); } if((heads & 2) == 2) { turtle.left(Math.PI - arrowAngle); turtle.forward(arrowSize); turtle.penup(); turtle.backward(arrowSize); turtle.pendown(); turtle.left(2 * arrowAngle); turtle.forward(arrowSize); } } function dashedLine(x1, y1, x2, y2, pattern = [500]) { turtle.jump(x1, y1); turtle.setheading(y2 > y1? Math.PI / 2: Math.PI / 2 * 3); let len = Math.sqrt((x2-x1)**2 + (y2-y1)**2); if(x1 != x2) { turtle.setheading((x2-x1 < 0? Math.PI: 0) + Math.atan((y2 - y1) / (x2 - x1))); } let tr = 0; let i = 0; turtle.penup(); while(tr < len) { let inc = pattern[i % pattern.length]; turtle.isdown()? turtle.penup(): turtle.pendown(); turtle.forward(inc + tr > len? len - tr: inc); i++; tr+=inc; } } //////////////////////////////////////////////////////////////// // Text utility code. Created by Reinder Nijhoff 2019 // https://turtletoy.net/turtle/1713ddbe99 //////////////////////////////////////////////////////////////// function Text() { class Text { print (t, str, scale = 1, italic = 0, kerning = 1) { t.radians(); let pos = [t.x(), t.y()], h = t.h(), o = pos; str.split('').map(c => { const i = c.charCodeAt(0) - 32; if (i < 0 ) { pos = o = this.rotAdd([0, 48*scale], o, h); } else if (i > 96 ) { pos = this.rotAdd([16*scale, 0], o, h); } else { const d = dat[i], lt = d[0]*scale, rt = d[1]*scale, paths = d[2]; paths.map( p => { t.up(); p.map( s=> { t.goto(this.rotAdd([(s[0]-s[1]*italic)*scale - lt, s[1]*scale], pos, h)); t.down(); }); }); pos = this.rotAdd([(rt - lt)*kerning, 0], pos, h); } }); } rotAdd (a, b, h) { return [Math.cos(h)*a[0] - Math.sin(h)*a[1] + b[0], Math.cos(h)*a[1] + Math.sin(h)*a[0] + b[1]]; } } const dat = ('br>eoj^jl<jqirjskrjq>brf^fe<n^ne>`ukZdz<qZjz<dgrg<cmqm>`thZhw<lZlw<qao_l^h^e_caccdeefg'+ 'gmiojpkqmqporlshsercp>^vs^as<f^h`hbgdeeceacaab_d^f^h_k`n`q_s^<olmmlolqnspsrrspsnqlol>]wtgtfsereqfph'+ 'nmlpjrhsdsbraq`o`makbjifjekckaj_h^f_eaecffhimporqssstrtq>eoj`i_j^k_kajcid>cqnZl\\j_hcghglhqjulxnz>c'+ 'qfZh\\j_lcmhmllqjuhxfz>brjdjp<egom<ogem>]wjajs<ajsj>fnkojpiojnkokqis>]wajsj>fnjniojpkojn>_usZaz>`ti'+ '^f_dbcgcjdofrisksnrpoqjqgpbn_k^i^>`tfbhak^ks>`tdcdbe`f_h^l^n_o`pbpdofmicsqs>`te^p^jfmfogphqkqmppnrk'+ 'shserdqco>`tm^clrl<m^ms>`to^e^dgefhekenfphqkqmppnrkshserdqco>`tpao_l^j^g_ebdgdlepgrjsksnrppqmqlping'+ 'kfjfggeidl>`tq^gs<c^q^>`th^e_dadceegfkgnhpjqlqopqorlshserdqcocldjfhigmfoepcpao_l^h^>`tpeohmjjkikfjd'+ 'hcecddaf_i^j^m_oapepjoomrjshserdp>fnjgihjikhjg<jniojpkojn>fnjgihjikhjg<kojpiojnkokqis>^vrabjrs>]wag'+ 'sg<amsm>^vbarjbs>asdcdbe`f_h^l^n_o`pbpdofngjijl<jqirjskrjq>]xofndlcicgdfeehekfmhnknmmnk<icgefhfkgmh'+ 'n<ocnknmpnrntluiugtdsbq`o_l^i^f_d`bbad`g`jambodqfrislsorqqrp<pcokompn>asj^bs<j^rs<elol>_tc^cs<c^l^o'+ '_p`qbqdpfoglh<chlhoipjqlqopqorlscs>`urcqao_m^i^g_eadccfckdnepgrismsorqprn>_tc^cs<c^j^m_oapcqfqkpnop'+ 'mrjscs>`sd^ds<d^q^<dhlh<dsqs>`rd^ds<d^q^<dhlh>`urcqao_m^i^g_eadccfckdnepgrismsorqprnrk<mkrk>_uc^cs<'+ 'q^qs<chqh>fnj^js>brn^nnmqlrjshsfreqdndl>_tc^cs<q^cl<hgqs>`qd^ds<dsps>^vb^bs<b^js<r^js<r^rs>_uc^cs<c'+ '^qs<q^qs>_uh^f_daccbfbkcndpfrhslsnrppqnrkrfqcpan_l^h^>_tc^cs<c^l^o_p`qbqepgohlici>_uh^f_daccbfbkcnd'+ 'pfrhslsnrppqnrkrfqcpan_l^h^<koqu>_tc^cs<c^l^o_p`qbqdpfoglhch<jhqs>`tqao_l^h^e_caccdeefggmiojpkqmqpo'+ 'rlshsercp>brj^js<c^q^>_uc^cmdpfrisksnrppqmq^>asb^js<r^js>^v`^es<j^es<j^os<t^os>`tc^qs<q^cs>asb^jhjs'+ '<r^jh>`tq^cs<c^q^<csqs>cqgZgz<hZhz<gZnZ<gznz>cqc^qv>cqlZlz<mZmz<fZmZ<fzmz>brj\\bj<j\\rj>asazsz>fnkc'+ 'ieigjhkgjfig>atpeps<phnfleiegfehdkdmepgrislsnrpp>`sd^ds<dhffhekemfohpkpmopmrkshsfrdp>asphnfleiegfeh'+ 'dkdmepgrislsnrpp>atp^ps<phnfleiegfehdkdmepgrislsnrpp>asdkpkpiognfleiegfehdkdmepgrislsnrpp>eqo^m^k_j'+ 'bjs<gene>atpepuoxnylzizgy<phnfleiegfehdkdmepgrislsnrpp>ate^es<eihfjemeofpips>fni^j_k^j]i^<jejs>eoj^'+ 'k_l^k]j^<kekvjyhzfz>are^es<oeeo<ikps>fnj^js>[y_e_s<_ibfdegeifjijs<jimfoeretfuius>ateees<eihfjemeofp'+ 'ips>atiegfehdkdmepgrislsnrppqmqkphnfleie>`sdedz<dhffhekemfohpkpmopmrkshsfrdp>atpepz<phnfleiegfehdkd'+ 'mepgrislsnrpp>cpgegs<gkhhjfleoe>bsphofleieffehfjhkmlompopporlsisfrep>eqj^jokrmsos<gene>ateeeofrhsks'+ 'mrpo<peps>brdejs<pejs>_ubefs<jefs<jens<rens>bseeps<pees>brdejs<pejshwfydzcz>bspees<eepe<esps>cqlZj['+ 'i\\h^h`ibjckekgii<j[i]i_jakbldlfkhgjkllnlpkrjsiuiwjy<ikkmkojqirhthvixjylz>fnjZjz>cqhZj[k\\l^l`kbjci'+ 'eigki<j[k]k_jaibhdhfihmjilhnhpirjskukwjy<kkimiojqkrltlvkxjyhz>^vamakbhdgfghhlknlplrksi<akbidhfhhill'+ 'nmpmrlsisg>brb^bscsc^d^dsese^f^fsgsg^h^hsisi^j^jsksk^l^lsmsm^n^nsoso^p^psqsq^r^rs').split('>').map( r=> { return [r.charCodeAt(0)-106,r.charCodeAt(1)-106, r.substr(2).split('<').map(a => {const ret = []; for (let i=0; i<a.length; i+=2) {ret.push(a.substr(i, 2).split('').map(b => b.charCodeAt(0) -106));} return ret; })]; }); return new Text(); }