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();
}