Desenhe o ☣ (símbolo de risco biológico)

66

Desenhe o símbolo de risco biológico em uma cor arbitrária em um fundo de cores distintas. As proporções específicas foram publicadas na edição de 27 de junho de 1974 do Federal Register do governo dos EUA.

Detalhes

  • Como saída, a gravação em um arquivo (formatos de varredura e vetor são permitidos) ou a exibição na tela são permitidos.

  • Você pode desenhar apenas a borda ou a forma preenchida.

  • Se você usar imagens rasterizadas, use um parâmetro (ou dois) como entrada que permita ajustar a resolução da saída (por exemplo, largura / altura).

  • O plano de fundo deve ter pelo menos o tamanho da caixa delimitadora do símbolo, mas pode ser maior.

  • A saída do símbolo unicode ☣ não é suficiente .

  • As proporções exatas das distâncias usadas são fornecidas no diagrama a seguir (que era originalmente daqui ):

Também tentei fazer um diagrama adicional com as mesmas medidas que, espero, seja um pouco mais fácil de ler:

(Inspirado em um post em 99% invisível )

flawr
fonte
2
Brecha: podemos colocar uma imagem de 1 x 1 pixel dentro de um plano de fundo de tamanho variável?
John Dvorak
Acho que não, se você definir a resolução suficientemente grande, o símbolo ainda deve aparecer. E, de qualquer forma, espero que as pessoas aqui tenham senso comum suficiente para entender o que queremos dizer :)
flawr
11
Se eu tivesse tempo de sobra, tentaria com PostScript ou gráficos de tartaruga.
Guy Coder
11
@ SriotchilismO'Zaic O comprimento é determinado pelos dois círculos: cada um tem um centro e raio, de modo que o comprimento é determinado pelo tamanho da lacuna.
flawr 5/09
11
Isso é "E" no diagrama original (as cruzes representam os centros dos círculos) e no que eu adicionei abaixo (onde o raio encontra o eixo de simetria). 11
flawr 5/09

Respostas:

96

T-SQL, 442 441 426 355 349 344 bytes

DECLARE @ VARCHAR(MAX)=REPLACE(REPLACE(REPLACE('DECLARE @a5MULTIPOINT((0 31),(19 -2),(-19 -2))'',@b5MULTIPOINT((0 39),(26 -6),(-26 -6))'',@5POINT(0 9)'',@d5LINESTRING(0 9,0 99,90 -43,0 9,-90 -43)''SELECT @a830%b821)%86)%d81)%d84%819))).STUnion(@827%820)).STIntersection(@b819)))'
,8,'.STBuffer('),5,' GEOMETRY='''),'%',').STDifference(@')EXEC(@)

Economizou mais de 70 bytes usando REPLACE()palavras-chave longas e executando como SQL dinâmico. Veja o código pós-substituição na captura de tela abaixo.

Dobrei os valores das coordenadas da ilustração da amostra e subi 9 unidades, para reduzir o número de casas decimais exibidas.

Isso foi feito no SQL 2017, usando os recursos geoespaciais introduzidos no SQL 2008. Muitas funções úteis de geometria interna, incluindo STBuffer, o que me fornece uma maneira simples de definir círculos de tamanhos diferentes em torno de um ponto.

Visual da saída, com código anotado:

Símbolo de risco biológico em T-SQL usando funções geoespaciais

Para mais desenho T-SQL, veja meu coelhinho da Páscoa .

Para aplicações mais práticas desta tecnologia em SQL, leia este artigo ou assista a este vídeo . SE ainda tem um site relacionado, gis.stackexchange.com .

Editar% s:

  1. Economizou 1 byte alterando uma coordenada de 104 para 99.
  2. Salva 15 bytes tirando STDifferenceum STUniondos objetos, em vez de cada um individualmente.
  3. Economizou 71 bytes usando REPLACE()palavras-chave repetidas e executando como SQL dinâmico. Revertido Edit 2, para deixar mais substituições de STDifference.
  4. Economizou 4 bytes movendo o centro para cima 9 unidades, o que alterou algumas coordenadas para dígitos únicos (negativos). Isso também liberou o numeral 5para usar como um caractere de substituição em vez de '#', economizando mais 2 bytes entre aspas.
  5. Economizou 5 bytes movendo )- se para a STDifferencesequência de substituição; obrigado, @Nicholas!
BradC
fonte
56
Por que ... isso existe?
Alexander
26
@Alexander Para bancos de dados que contêm ou usam dados geográficos, como censo populacional ou estudos científicos, ou mesmo apenas vendas de clientes por região geográfica. Ou apenas para desenhar coelhos e símbolos de risco biológico.
BradC 5/09
24
O SQL é ruim o suficiente para a única coisa a que se destina, que em sã consciência gostaria de ir além disso. Imagine GUIs escritas em SQL. Preciso de anotações, aspectos e uma estrutura de teste de unidade. Precisamos ir mais fundo .
Alexander
24
@Alexander Como você deseja: TSQLT
FreeMan
15
@FreeMan Oh, pelo amor de Deus.
Alexander
32

Tex + Tikz, 232 bytes

43 bytes salvos mudando para tex. Agradecimentos a Phelype Oleinik

Alguns bytes salvos graças ao Skillmon

\input tikz \tikz[x=1,y=1,white]{\def\f{\foreach\1in{90:,210:,330:}}\def\u{\draw[line width=}\def~{circle(}\f\fill[red](\122)~30);\f{\u2](0,)--(\111);\u8](\130)--(\160);\fill(\130)~21);}\fill~6);\u7,red]~23.5);\f\u2](\130)~20);}\bye

Com quebras de linha e sem \def:

\input tikz
\tikz[x=1,y=1,white]{
\foreach\1in{90,210,330}\fill[red](\1:22)circle(30);
\foreach\1in{90,210,330}{
\draw[line width=2](0,0)--(\1:11);
\fill(\1:30)circle(21);
\draw[line width=8](\1:30)--(\1:60);
}
\fill(0,0)circle(6);
\draw[line width=7,red](0,0)circle(23.5);
\foreach\1in{90,210,330}\draw[line width=2](\1:30)circle(20);
}
\bye

Explicação

Isso está um pouco desatualizado. Vou corrigi-lo quando puder descobrir como tornar as imagens não interessantes.

Aqui vou explicar como a resposta não compactada resolve o problema. Em algum momento, posso explicar como a compactação funciona. Primeiro, desenhamos os grandes círculos pretos:

\foreach\x in{90,210,330}\fill(\x:21)circle(30);

insira a descrição da imagem aqui

Então desenhamos algumas linhas brancas:

\foreach\x in{90,210,330}\draw[white,line width=2cm](0,0)--(\x:11);

insira a descrição da imagem aqui

Então desenhamos círculos brancos:

\foreach\x in{90,210,330}\fill[white](\x:30)circle(21);

insira a descrição da imagem aqui

Em seguida, adicionamos um círculo branco central:

\fill[white](0,0)circle(6);

insira a descrição da imagem aqui

Em seguida, adicionamos um anel preto:

\draw[line width=7cm](0,0)circle(25.5);

insira a descrição da imagem aqui

Em seguida, removemos partes do anel preto

\foreach\x in{90,210,330}\draw[white,line width=2cm](\x:30)circle(20);

insira a descrição da imagem aqui

Assistente de Trigo
fonte
9
Você não atenuou os seis pontos externos. Deve haver 4 unidades de espaço em branco entre cada par.
Level River St
11
@LevelRiverSt Os seis pontos externos agora estão a 4 unidades do parceiro.
Wheat Wizard
2
Essas "pontas das garras" são muito pontudas; devem consistir em segmentos de linha reta paralelos aos segmentos provenientes do círculo central. Também o 20.88 parece bastante suspeito.
flawr 5/09
Você pode salvar outro byte usando em \1vez de \x, como você pode usar \def\f{\foreach\1in{90,210,330}}.
Skillmon
11
@ flawr bem ... agora eles estão literalmente um pouco menores que 5000x5000 ... apenas 90x90 agora ... mal conseguem entender os detalhes: D
Nelson
15

C, 8010 bytes

Muito antes, antes de SVG ou EMF, era necessário lidar com a varredura e, se você queria que algo fosse carregado imediatamente, diga antes que o sistema operacional estivesse pronto, como uma tela de inicialização do Windows, era necessário usar RLE ou duração -codificação. Esse monstro gera um arquivo PBM usando RLE como dados. Construa como de costume e execute assim ./biohazard > biohazard.pbm.

Se você incluísse todas as estruturas necessárias para gerar, por exemplo, o mecanismo SVG em HTML, as bibliotecas Java, etc., essa provavelmente seria a menor solução independente , porque putsé a única função externa e, normalmente, é uma das menores. stdio.hfunções.

Em relação a este detalhe:

Se você usar imagens rasterizadas, use um parâmetro (ou dois) como entrada que permita ajustar a resolução da saída (por exemplo, largura / altura).

Interpretei "deveria" como diferente de "must", por exemplo, como na RFC 2119 , então eu não incluem dimensionamento, porque para este código só seria viável fazer múltiplos do original, por exemplo, ./biohazard 2e que iria introduzir atoi, printfe outros complicações que prejudiquem o foco principal da submissão.

int o,i,x[]=
{4946,3,33,2,389,8,33,8,378,13,33,13,369,17,33,16,363,20,33,20,356,19,41,19,350,18,49,18,344,18,55,18,339,17,61,17,334,
17,66,17,330,17,71,17,325,17,75,17,321,17,79,17,317,17,83,17,313,17,87,16,311,16,90,17,307,17,93,17,303,17,97,17,300,
17,99,17,297,17,102,18,293,18,105,17,291,18,107,18,288,17,110,18,285,18,113,17,283,18,115,18,280,18,117,18,277,19,119,
18,275,19,121,19,272,19,123,19,270,19,125,19,268,19,127,19,266,19,129,19,263,20,131,19,261,20,133,19,259,20,134,20,257,
20,136,20,255,21,137,20,253,21,139,20,251,21,141,20,249,21,142,21,248,21,143,21,246,21,145,21,244,21,146,22,242,22,147,
22,240,22,149,22,238,22,150,22,238,22,151,22,236,22,152,23,234,23,153,23,232,23,155,22,232,23,155,23,230,23,157,23,228,
24,157,24,226,24,159,23,226,24,159,24,224,24,160,25,222,25,161,24,222,24,162,25,220,25,163,25,219,25,163,25,218,25,164,
26,216,26,165,25,216,26,165,26,214,26,166,26,214,26,167,26,212,27,167,26,212,26,168,27,210,27,169,27,209,27,169,27,208,
27,170,28,207,27,170,28,206,28,171,27,206,28,171,28,204,29,171,28,204,28,172,29,202,29,172,29,202,29,173,29,201,29,173,
29,200,30,173,29,200,30,173,30,198,31,173,30,198,30,174,31,197,30,174,31,196,31,174,31,196,31,175,31,195,31,175,31,194,
32,175,31,194,32,175,32,193,32,175,32,193,32,175,32,192,33,175,32,192,33,175,33,191,33,175,33,190,34,175,33,190,34,175,
33,190,34,175,34,189,34,174,35,189,34,174,35,188,35,174,35,188,35,174,36,187,36,173,36,187,36,173,36,187,36,173,36,186,
37,74,25,74,36,186,37,67,39,67,36,186,37,62,49,61,38,185,37,58,57,57,38,185,38,53,64,54,38,185,38,50,71,50,38,185,38,
47,76,48,38,185,38,45,81,44,39,184,40,41,87,41,39,184,40,39,91,39,39,184,40,37,95,37,39,184,40,35,99,34,41,183,41,32,
103,32,41,183,41,30,107,30,41,183,41,28,111,27,42,183,42,25,115,25,42,183,42,24,117,24,42,183,42,22,121,21,43,183,43,
19,124,20,43,183,43,18,127,18,43,183,43,17,129,16,44,183,44,14,133,14,44,183,44,13,135,12,45,183,45,11,137,11,45,183,
45,10,139,9,46,183,46,9,138,10,46,183,46,10,137,9,47,183,47,9,136,10,47,183,47,10,135,9,48,183,48,10,56,20,57,10,48,
183,49,9,50,33,49,10,48,184,49,10,45,41,45,10,48,184,50,10,40,49,40,10,49,184,50,10,37,55,36,10,50,185,50,10,33,60,34,
10,50,185,51,10,30,65,30,10,51,185,51,11,27,69,27,10,52,185,52,10,25,73,24,11,52,185,53,10,22,77,21,11,53,185,53,11,19,
81,19,10,53,186,54,11,16,85,16,10,54,185,56,11,13,88,14,11,56,181,59,11,11,91,11,11,59,176,63,11,8,94,9,11,63,171,66,
11,6,97,6,11,66,167,68,12,4,99,4,11,69,163,71,12,1,102,2,11,72,159,74,126,75,155,77,124,78,151,80,123,79,149,82,120,83,
145,85,118,86,141,88,116,88,139,90,114,91,135,93,112,93,133,96,109,96,130,98,107,98,127,101,104,102,124,104,101,104,
122,106,99,106,119,110,95,109,117,112,93,112,114,115,89,115,112,118,85,118,110,120,82,121,107,124,78,124,105,127,74,
127,103,131,69,130,101,134,65,133,99,137,60,137,97,141,54,141,95,146,47,145,93,151,39,150,91,157,29,156,89,166,13,165,
88,168,9,168,86,169,9,169,84,170,9,170,82,171,9,171,80,172,9,171,79,173,9,172,78,173,9,173,76,174,9,174,74,175,9,175,
72,176,9,175,72,176,9,176,70,177,9,177,68,64,20,93,10,94,20,63,68,57,34,83,17,83,33,58,66,54,42,77,21,76,43,54,64,51,
50,71,25,71,49,51,64,48,57,65,29,65,56,49,62,46,63,61,31,61,62,47,60,45,67,58,33,58,67,44,60,43,71,55,35,54,72,43,58,
41,36,8,32,52,37,51,33,8,35,41,58,40,36,17,26,49,39,48,27,16,37,40,56,39,38,22,23,46,41,45,24,21,39,39,55,37,40,26,21,
43,42,44,21,26,40,37,54,36,42,29,20,41,43,41,20,29,42,36,53,35,43,29,21,39,44,39,22,29,43,35,52,34,45,29,23,37,45,37,
23,29,45,34,51,33,46,29,24,35,46,35,25,29,46,33,50,32,48,29,26,33,47,33,26,29,47,33,49,31,49,29,27,32,47,32,27,29,49,
31,48,31,49,30,28,30,48,30,29,29,50,31,47,29,51,30,30,28,49,28,30,29,51,30,46,29,52,29,32,27,49,27,31,29,53,28,46,28,
53,29,33,26,49,26,32,29,54,28,44,28,54,29,34,25,49,25,33,29,55,27,44,27,55,29,35,24,49,23,35,29,56,27,43,26,56,29,36,
22,50,22,36,29,57,26,42,26,57,29,37,21,50,21,37,29,58,26,41,25,58,29,38,21,49,20,38,29,59,25,40,25,59,29,39,20,49,19,
39,29,60,24,40,24,60,29,40,19,49,19,39,29,61,24,39,23,61,29,41,18,49,18,40,29,62,23,38,23,62,30,41,17,49,17,41,29,63,
22,38,22,63,30,42,16,48,17,42,29,63,23,37,21,65,29,43,16,47,16,43,29,64,22,36,22,65,29,43,16,47,15,44,29,65,21,36,21,
66,29,44,13,50,14,44,29,66,21,35,20,67,29,45,11,53,11,45,29,67,20,34,20,68,29,46,8,57,8,46,29,67,20,34,20,68,29,46,6,
61,5,46,30,68,19,34,19,69,29,47,4,63,4,46,30,69,19,33,18,70,30,47,1,67,1,47,29,70,19,32,19,70,30,163,29,71,18,32,18,71,
30,61,2,37,2,61,29,72,18,31,17,73,29,59,5,35,5,58,30,72,18,31,17,73,29,58,7,33,7,57,30,73,17,30,17,74,30,55,10,31,10,
55,30,73,17,30,17,74,30,53,13,28,14,53,30,74,16,30,16,75,30,51,17,25,16,52,29,75,17,29,16,76,29,50,20,21,19,50,30,76,
16,29,15,77,30,50,21,16,22,50,30,77,15,29,15,77,30,50,26,7,25,51,30,77,15,28,15,78,30,51,57,50,30,78,15,28,15,78,31,50,
56,51,30,79,15,27,14,80,30,51,55,51,30,79,15,27,14,80,30,51,55,50,31,80,14,27,13,81,31,51,53,51,30,81,14,27,13,82,30,
51,53,51,30,82,13,27,13,82,31,50,52,51,31,82,13,26,13,83,31,51,51,51,31,82,13,26,13,83,31,51,51,50,31,84,12,26,13,84,
31,50,50,51,31,84,12,26,12,85,31,51,49,50,32,84,13,25,12,85,32,50,49,50,31,86,12,25,12,86,31,50,48,50,32,86,12,25,11,
87,32,50,47,50,32,86,12,25,11,87,32,50,47,49,32,88,11,25,11,88,32,49,47,49,32,88,11,25,11,88,32,49,46,49,32,89,11,25,
10,90,32,49,45,49,32,89,11,25,10,90,33,48,45,48,33,90,10,25,10,91,32,48,45,47,33,91,10,25,10,91,33,47,44,48,33,91,10,
25,10,91,34,46,44,47,33,92,10,25,9,93,33,47,43,46,34,92,10,25,9,93,34,46,43,46,33,93,10,25,9,94,34,45,43,45,34,94,9,25,
9,94,35,44,43,44,34,95,9,25,9,95,34,44,42,44,35,95,9,25,9,95,35,43,42,44,34,96,9,25,9,96,35,42,42,43,35,96,9,25,8,97,
36,42,41,42,35,97,9,25,8,98,36,41,41,41,36,97,9,25,8,99,36,40,41,40,36,98,8,26,8,99,37,39,41,39,36,99,8,26,8,100,37,38,
41,38,37,99,8,27,7,100,38,37,41,37,37,101,7,27,7,101,38,36,41,36,38,101,7,27,7,102,38,35,41,35,38,102,7,27,7,102,39,34,
41,34,38,103,7,27,7,103,39,33,41,33,39,103,7,27,7,104,39,32,41,32,39,104,7,27,7,104,41,30,41,30,40,104,7,29,6,105,41,
29,41,29,40,105,7,29,6,106,41,28,41,28,41,105,7,29,6,107,42,26,41,26,42,106,7,29,6,108,42,25,41,25,42,107,7,29,7,107,
44,22,42,23,43,108,6,30,7,108,44,21,42,21,45,108,6,31,6,109,45,19,42,20,45,109,6,31,6,110,46,17,43,17,46,110,6,31,6,
111,47,15,43,15,47,111,6,31,6,112,48,13,43,13,48,112,5,33,5,113,49,11,43,10,50,112,6,33,5,114,50,9,43,9,50,113,6,33,6,
113,50,8,44,9,49,114,6,33,6,114,48,9,45,8,48,115,5,35,5,115,47,9,45,8,47,116,5,35,5,117,45,8,46,9,45,116,6,35,6,117,44,
8,46,9,44,117,5,37,5,118,42,9,47,8,43,118,5,37,5,119,41,9,47,9,41,119,5,37,5,120,40,8,48,9,40,119,5,39,5,120,39,8,48,9,
38,121,5,39,5,121,37,9,49,8,37,122,5,39,5,123,35,9,49,9,35,123,4,41,5,123,34,8,50,9,34,123,5,41,5,124,32,9,51,9,31,125,
5,42,3,127,30,9,51,9,30,127,3,43,1,130,28,9,52,9,29,130,1,176,26,9,53,9,26,310,24,9,54,9,24,314,22,9,55,9,22,317,20,9,
55,9,20,320,18,9,56,10,17,324,15,10,57,9,16,327,13,9,58,10,13,331,10,10,59,9,11,335,8,9,60,10,8,339,5,10,61,9,6,344,2,
9,62,10,2,358,63,368,65,367,65,366,67,365,67,364,69,362,70,362,71,360,73,358,75,356,76,356,77,354,79,352,81,350,82,349,
84,215,2,130,86,130,3,79,5,129,87,128,6,77,6,127,89,126,6,79,6,125,91,124,7,80,6,123,93,122,7,82,6,121,95,120,7,84,6,
119,97,118,7,86,7,115,100,116,7,87,8,113,102,114,7,89,8,111,105,111,7,91,8,109,107,109,7,93,8,107,109,106,9,94,9,103,
112,104,9,96,9,101,115,101,9,98,10,97,118,98,10,100,10,95,121,95,10,102,11,91,124,92,11,104,11,89,127,88,11,107,12,85,
131,85,11,110,12,81,135,81,12,112,13,77,138,78,13,114,14,73,143,73,14,116,15,69,72,2,73,69,15,118,17,63,74,5,73,64,16,
122,17,59,75,7,75,58,18,124,19,53,77,9,77,53,19,126,22,45,79,13,78,46,21,130,24,37,82,15,81,38,24,132,28,27,85,18,86,
27,28,135,37,5,95,21,95,5,37,138,134,24,135,141,131,27,131,144,128,31,127,148,124,34,125,151,121,37,121,155,117,41,117,
159,113,45,113,163,109,49,109,167,105,53,105,171,101,57,101,175,96,62,96,181,91,67,91,185,86,72,86,191,80,78,81,196,74,
84,74,204,67,91,67,211,59,99,59,219,51,107,51,228,40,119,39,242,25,133,25,5311,0};
main(){for(puts("P1\n432 408");x[i];++i,o=!o)while(x[i]--)puts(o?"0":"1");}
mbomb007
fonte
11
Seria bom explicar como você gerou o código.
Cœur
O código gera uma nova linha após cada caractere; Eu acho que você precisa putchar()ou similar.
marcelm 6/09
@marcelm - O formato PBM P1 está bem com isso!
11
Tenho certeza de que isso deve significar obrigação para essa pergunta, mas provavelmente valeria a pena ser aceito pelo OP.
Wheat Wizard
11
Não acho que o uso deva necessariamente significar que há uma distinção. Essa é realmente uma pergunta que você deve (ou talvez deve) fazer ao OP.
Wheat Wizard
15

TeX + Ti k Z, 234 230 226 bytes

Originalmente 5 bytes a mais que a resposta do Sriotchilism O'Zaic , mas este deve estar correto. É semelhante à sua resposta, mas economiza mais alguns bytes aqui e ali, e precisa de \draw[line width=8]mais um (no código abaixo isso é feito \28](~30)to(~55);, são 17 bytes adicionados apenas para isso) para acertar as dicas do símbolo, daí os 5 bytes mais comprimento geral do código.

E, graças ao Sriotchilism O'Zaic, reli algumas das perguntas e percebi que posso mudar a cor para vermelho, para salvar alguns bytes novamente:

\input tikz\let~\def~\1{circle(}~\2{\draw[line width=}~~{\foreach~in{90:,210:,330:}}\tikz[x=1,y=1,white]{~\fill[red](~22)\130);~{\fill(~30)\121);\28](~30)to(~55);\22](~0)to(~10);}\fill\16);\27,red]\123.5);~\22](~30)\120);}\bye

TeX-g + Ti k Z, 195 bytes

Apenas se alguém se importa, o seguinte usa um dialeto de golfe com código baseado em TeX no qual estou trabalhando (não considere o código estável). A contagem de bytes inclui caracteres EOL e caracteres EOF, pois esses são usados ​​semanticamente (o EOL delimita argumentos de loops). O dialeto é muito pequeno até agora e apresenta apenas atalhos para definições e uma sintaxe para loop, no entanto, não foi escrito especificamente para esta resposta, portanto não deve violar as regras do código de golfe. Repositório do -g.texarquivo -package /: https://github.com/Skillmon/TeX-g

\input-g <tikz>~"{\:~{90:,210:,330:}}~'{circle(}~_{\draw[line width=}!f\fill\tikz[x=1,y=1,white]{"f[red](~22)'30);
"f(~30)'21);_8](~30)to(~55);_2](~0)to(~10);
f'6);_7,red]'23.5);"_2](~30)'20);
}

A saída dos dois trechos de código parece idêntica:

insira a descrição da imagem aqui

( com preguiça de atualizar a imagem, imagine-a vermelha )

Skillmon
fonte
Minha resposta agora está correta e 2 bytes menor que a sua. Tenho certeza de que alguém provavelmente poderia combinar algumas das minhas respostas com as suas para fazer uma mais curta, mas não entendo bem sua resposta.
Wheat Wizard
@ SriotchilismO'Zaic se eu mudar a cor para vermelho (exagero na regra de que a cor pode ser arbitrária), obtenho-a em 230 bytes.
Skillmon
@ SriotchilismO'Zaic e, obviamente, você salvou mais de um byte na sua resposta olhando para a minha (apenas dizendo).
Skillmon
Ok, olhei para a sua resposta e não entendi o que estava fazendo, então acho que não poderia ter tirado muito dela. Mas mudei a mensagem para remover um número exato de qualquer maneira, pois talvez eu tenha pegado algumas coisas da sua resposta sem perceber.
Wheat Wizard
2
@ SriotchilismO'Zaic está tudo bem. Meu código é influenciado pelo seu, afinal, atualmente eu tento escrever um pacote de código de golfe para transformar o TeX em uma linguagem de código de algum tipo. Quando finalmente a publiquei, minha resposta será mais curta :) (este não é um idioma criado especificamente para esta pergunta, portanto não quebra as regras)
Skillmon
12

GLSL, 700 629 564 545 499 bytes

#define v vec2
#define j(x,r)length(x-g)<r
#define k(x,r,q)j(x,q)!=j(x,r)
#define l(b)length(g-b)<1.&&length(g-dot(g,b)*b)<(length(g)<S?A*S:A/S)
float C=.86,S=.5,F=.3,E=.22,A=.02,G=.21;void mainImage(out vec4 o,in v p){v r=iResolution.xy;v g=(p/S-r)/r.y;o.g=(k(v(0,F),G,G-A)||k(v(F*C,-F*S),G,G-A)||k(v(-F*C,-F*S),G,G-A))?o.g=0.:k(v(0),F,G)?C:l(v(0,1))||l(v(C,-S))||l(v(-C,-S))||j(v(0),.06)||j(v(0,F),G)||j(v(F*C,-F*S),G)||j(v(-F*C,-F*S),G)?0.:j(v(0,E),F)||j(v(E*C,-E*S),F)||j(v(-E*C,-E*S),F)?C:0.;}

Eu estava brincando com Shadertoy, então tentei a linguagem de sombreamento GLSL. O código apenas rasteriza círculos e linhas testando cada fragmento e atribui a eles um valor de um ou zero. O tamanho foi reduzido de> 1000 bytes pelo uso intenso de macros.

Programa Shadertoy

insira a descrição da imagem aqui

Roninkoi
fonte
11
Bem vindo ao site! Pura primeira resposta!
Wheat Wizard
Eu não sei o idioma, mas pode o &&e ||ser golfed para &e |em algumas ou todas as partes?
Kevin Cruijssen 6/09
@KevinCruijssen É um subconjunto de C, então essas seriam operações bit a bit. Para mim, o compilador reclama do tipo
Roninkoi 6/09
11
@ Roninkoi Eu realmente vi que era baseado em C. Em C, é possível usar |/ em &vez de ||/ &&para bools, não é? Não faz nada em C há muito tempo, então não tenho certeza. Eu sei que funciona em Java / C # .NET na maioria dos casos. Mas só agora percebo o link Shadertoy que você adicionou, e ele não parece funcionar lá como você já declarou. Ah bem. Nice primeira resposta btw! Bem-vindo ao CGCC.
Kevin Cruijssen 6/09
Cortei -30 bytes no código publicado, mas o cabeçalho sais 566 bytes e o código publicado é 628?
PrincePolka
12

SVG (HTML5), 434 410 321 bytes

<svg><circle cx=60 cy=60 r=23.5 stroke-width=7 fill=#fff stroke=#000 /><use href=#g transform=translate(120,0)scale(-1,1) /><g id=g><use href=#p transform=rotate(120,60,60) /><use href=#p transform=rotate(240,60,60) /><path id=p stroke=#fff stroke-width=2 d=M55,60A5,5,0,0,1,60,55V50A20,20,0,0,1,58,10V7A31,31,0,0,0,29,43

Agora, com base no SVG do @ LevelRiverSt.

Neil
fonte
11
Eu acredito que omitir <defs>é seguro. Isso funciona para mim no Firefox, Chrome e Edge.
Arnauld
@ Arnauld Obrigado, isso significa que posso me livrar do primeiro <use>também!
Neil
12

Processando, 371 368 bytes

translate(width/2,width/2);scale(width/99);int i=0,b=204;float t=TAU/3;noStroke();for(;i<3;i++){fill(0);ellipse(0,-22,60,60);rotate(t);}for(;i<6;i++){fill(b);rect(-4,-60,8,16);ellipse(0,-30,42,42);rotate(t);}ellipse(0,0,12,12);stroke(0);strokeWeight(7);noFill();ellipse(0,0,47,47);for(;i<9;i++){strokeWeight(2);stroke(b);ellipse(0,-30,40,40);line(0,0,0,-9);rotate(t);}

Não tinha certeza se o processamento deveria contar como rasterizado ou não para o objetivo deste desafio. Se ele conta como rasterized, o translatee scaleé necessário fazer o símbolo legível e na tela para um determinado tamanho da janela. Mas, como todos os comandos de desenho são vetorizados, ele funciona em qualquer escala; portanto, se assumirmos que desenhar na origem relativa com cerca de 200 unidades de largura é bom, os primeiros 43 bytes podem ser eliminados.

Isso pressupõe que a cor de fundo seja 204, 204, 204, que é a cor de fundo padrão no processamento. Ele também assume um rectModede CORNERe um ellipseModede CENTER(os padrões)

Com uma inicial size(640, 640), o esboço resultante fica assim:

insira a descrição da imagem aqui

Ao dobrar a escala, salvei 3 bytes, porque .5s são eliminados (embora vários números fluam de 1 a 2 dígitos).

A construção é semelhante à solução TeX, desenhando preto e cinza no topo para "apagar" as lacunas entre a forma.

Explicação:

translate(width/2,width/2); // Move to the middle of the canvas
scale(width/99);            // Scale up to fill the canvas

int i=0,b=204;              // Initialize i, and `b` to the background color
float t=TAU/3;              // Save a rotation of one third, in radians

noStroke();
for(;i<3;i++){ // Draw the three big black circles
  fill(0);
  ellipse(0,-22,60,60);
  rotate(t);
}
for(;i<6;i++){
  fill(b);
  rect(-4,-60,8,16);     // "Blunt" the corners on the sharp outer rings
  ellipse(0,-30,42,42); // Cut out the middle of the big circles
  rotate(t);
}
ellipse(0,0,12,12); // Cut out the small circle in the middle
stroke(0);
strokeWeight(7);
noFill();
ellipse(0,0,47,47); // Draw the thick band that goes through all three big circles
for(;i<9;i++){
  strokeWeight(2);
  stroke(b);
  ellipse(0,-30,40,40); // Cut the "gap" between the three big rings
                        //and the band passing through them
  line(0,0,0,-16);      // Cut the lines coming out of the small middle circle
  rotate(t);
}
Curtis Fenner
fonte
Parece bom :) Acho que se você dobrar todas as medidas, poderá evitar o .5!
flawr 5/09
Sim, mas isso também mudaria parte do número de um dígito para dois dígitos, então não tenho certeza de como ele se equilibra. Se eu contei direito, parece que isso salvaria 2 bytes. Eu também estava pensando em usar um scalepara mudá-lo para apenas uma parte do código, mas não tinha certeza de onde a melhor colocá-lo
Curtis Fenner
oh você está certo, eu não considerei isso.
flawr 5/09
Dobrar as medidas para remover decimais economizou quase 10 bytes na minha resposta, mesmo que algumas cordas passassem de um para dois dígitos. Vale a pena tentar, de qualquer maneira.
BradC 5/09
11
Eu salvei 3 bytes dobrando a escala em que é desenhada. @IsmaelMiguel
Curtis Fenner
9

GLSL, 319 310 bytes

#define F float
#define H(y)sqrt(x*x+(y)*(y))
void mainImage(out vec4 D,in vec2 u){vec2 U=u*.003-.5;F x=abs(U.x),y=U.y;if(y<.577*x){F t=.5*x+.866*y;y=.866*x-.5*y;x=abs(t);}F c=F(H(y-.11)<.15);F R=H(y);F S=H(y-.15);if(S<.105)c=0.;if(R<.03)c=0.;if(x<(R<.1?.005:.02))c=0.;if(R>.10&&R<.135&&S<.095)c=1.;D=vec4(c);}

Isso pode ser renderizado em Shadertoy .

amostra

Você pode usar a simetria na imagem para desenhá-la com uma quantidade menor de formas separadas.

Aqui está uma versão um pouco inflada:

#define F float
#define H(y) sqrt(x*x+(y)*(y))

void mainImage(out vec4 D,in vec2 u)
{
    // normalized UV
    vec2 U = u*.003 - .5;

    // fold the 6 identical sections to the same UV coordinates
    F x = abs(U.x), y = U.y;
    if (y < .577*x)
    {
        F t = .5*x + .866*y;
        y = .866*x - .5*y;
        x = abs(t);
    }

    // circles and lines
    F c = F(H(y-.11) < .15);
    F R = H(y);
    F S = H(y-.15);
    if (S < .105) c = 0.;
    if (R < .03) c = 0.;
    if (x < (R < .1 ? .005 : .02)) c = 0.;
    if (R > .10 && R < .135 && S < .095) c = 1.;

    // output
    D = vec4(c);
}

(obrigado a @Kevin Cruijssen por remover alguns espaços em branco desnecessários)

Roeland
fonte
11
Você pode remover alguns dos espaços. O que você define: H(y) sqrtH(y)sqrt; todos os espaços nas suas declarações if: if (if(; e aqueles em sua última declaração if envolvendo os ANDs: if (R>.10 && R<.135 && S<.095)c=1.;if(R>.10&&R<.135&&S<.095)c=1.;.
Kevin Cruijssen 6/09
8

HTML / JS,  448 435 433  387 bytes

Economizou muitos bytes usando a versão pré-minimizada do SVG do @ Neil
Economizou 2 bytes graças ao @Shaggy

Uma versão compactada deste arquivo SVG do Wikimedia Commons.

<body onload="_=`<svg~12y~24y><path id=p d=m28.8117,27.046a3,3}0qb3117q4.004v-1w539|1wq20.7959v-w583a1jxb7975x7.3228xj,8.6032x9.7443l-.4835q.2792|-18.7598q9.0989zm3.4148q8.871a10x0}0q1b453,c9w,9w{-kx3wx3w}1x6.8042,0x0x0{k>~><use href=#p transform=rotate(},cc|a10wx0w}c{}1qb1756,yc26,26) /x,1w.5q,-kb7417j5x5}1c0,b2.`;for(i of`bcjkqwxy{|}~`)with(_.split(i))_=b.innerHTML=join(pop())"id=b>

Experimente online! (apenas gera a string descompactada)

Snippet de demonstração

Arnauld
fonte
Isso funciona no CodePen no Chrome Android, para 392.
Shaggy
11
@ Arnauld Eu inverti minha resposta, embora custe 5 bytes (encontrei outro byte desnecessário, de modo que, no geral, minha pontuação aumentou apenas 4).
Neil
@ Neil Atualizado em conformidade. ;)
Arnauld
Acontece que o SVG do @ LevelRiverSt é muito menor!
Neil
7

Haskell , 530 491 436 435 430 420 bytes

f=fromIntegral
c(a,b)r(x,y)=(x-a)^2+(y-b)^2<r^2
(m#w)t(x,y)|c<-cos(-t),s<-sin(-t)=x*c-y*s>m&&abs(x*s+y*c)<w/2
u a p=any($p)a
i a p=all($p)a
v=(*(pi/6))<$>[9,5,1]
o=c(0,0)
h?r=[c(h*cos a,h*sin a)r|a<-v]
(h%y)x|u[i[u$11?15,(not.)$u$o 3:map(0#1)v++map(9#4)v++15?10.5],i[o 13.5,not.(o 10),u$15?9.5]](60*f x/h-30,60*f y/h-30)="0 "|0<1="1 "
g h|s<-show h,n<-[0..h-1]=writeFile"a.pbm"$unlines$"P1":(s++' ':s):[n>>=(f h%)y|y<-n]

Produz um arquivo PBM.

Isso foi muito divertido!

Risco biológico

(Eu tive que converter isso em PNG para fazer upload para imgur)

Basicamente, criamos nossas próprias funções de gráficos vetoriais que são renderizadas em uma imagem pixel por pixel, detectando se o pixel faz parte da forma. A forma é construída como um monte de círculos e linhas (irradiando da origem) mantidos juntos com operações básicas do conjunto: união, interseção e não. Os círculos são compostos de seu centro e um raio, e as linhas têm um raio mínimo, uma largura e um ângulo nessa ordem. É fácil detectar a participação em um círculo: subtraio as cordas centrais e comparo a magnitude ao raio. A linha é um pouco mais complicada: eu giro o ponto pelo oposto do ângulo para trazê-lo (para anular a rotação) e apenas verifico se as coordenadas xey estão dentro do intervalo esperado. O raio mínimo é garantir que o espaço maior nas extremidades dos grandes círculos não anule os pequenos espaços próximos ao centro. Depois disso, é uma simples questão de lógica booleana definir a matemática.

EDIT: Muito obrigado a @flawr por descolar 39 bytes!

EDIT2: Muito obrigado a @Christian Sievers por descolar 55 bytes! Boa ideia transformá-los em funções

EDIT3: Mais uma vez obrigado a @Christian Sievers por cortar outro byte!

EDIT4: Retirou 7 bytes graças a @ H.PWiz e @Angs!

EDIT5: Acabei de perceber um bug! Eu estava processando as linhas duas vezes mais grossas do que deveriam! Custou-me 2 bytes para corrigi-lo (tinha que dividir a largura por 2; poderia ter ajustado os valores constantes, mas alterar 1 para 0,5 também custaria 2).

EDIT6: Obrigado @ Angs por decolar outros 10 bytes!

user1472751
fonte
Uau, isso é tão legal. É raro ver alguém definindo seus próprios tipos no código-golfe aqui :) Duas perguntas: É necessário ter ângulos negativos [-90,-210,-330]? E seria possível alterar o <=para <?
flawr 6/09
11
Então eu tentei e consegui raspar alguns bytes
flawr 6/09
11
Ah, caso você não saiba, temos um bate-papo sobre haskell e algumas dicas para jogar golfe em haskell .
flawr 6/09
11
Outro pequeno ajuste
flawr 6/09
11
Agradável! É possível sem tipo de dados
Christian Sievers
6

Ruby , 278 bytes

puts"<svg viewBox='-60-60 120 120'><circle cx='0'cy='0'r='23.5'stroke-width='7'fill='white'stroke='red'/>",(-3..5).map{|i|"<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(#{i/3},-1)rotate(#{i*120})'/>"}

Experimente online!

Gera o código SVG abaixo, com o símbolo em 200% da escala no OP.

Consiste em um círculo na parte de trás e as pontas em primeiro plano. A ponta é dimensionada -1,0,1no Xeixo e girada em múltiplos de 120 graus. Os casos em que a Xescala é zero não produzem saída, enquanto o -1e +1. forneça os dois lados de cada par de pinos.

Utiliza-se uma borda branca de duas unidades de largura em torno da ponta para cortar o círculo traseiro, usando os atributos strokee stroke-width. Para que a forma interna seja de acordo com o OP, as coordenadas são movidas por 1 unidade (metade da largura da borda). Observe que o caminho não foi deliberadamente fechado para suprimir o desenho da linha final da borda. Isso garante que as duas metades de cada par de pinos se juntem.

90 graus do círculo interno são desenhados em vez dos 60 esperados, por razões de golfe. Isso significa que há alguma sobreposição entre as bases de cada par de pinos, mas isso não afeta a aparência da forma de saída.

<svg viewBox='-60-60 120 120'><circle cx='0'cy='0'r='23.5'stroke-width='7'fill='white'stroke='red'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(-1,-1)rotate(-360)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(-1,-1)rotate(-240)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(-1,-1)rotate(-120)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(0,-1)rotate(0)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(0,-1)rotate(120)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(0,-1)rotate(240)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(1,-1)rotate(360)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(1,-1)rotate(480)'/>
<path fill='red'stroke='white'stroke-width='2'd='M5 0A5 5 0 0 1 0 5v5A20 20 0 0 1 2 50v3A31 31 0 0 0 31 17'transform='scale(1,-1)rotate(600)'/>

Level River St
fonte
6

PostScript , 367 359 328 271 bytes

Código (versão compactada):

5 5 scale 36 24 translate <</c{0 360 arc closepath}/r{120 rotate}/R{repeat}/L{setlinewidth}/g{setgray}/F{fill}>>begin 3{0 11 15 c F r}R 1 g 3{0 15 10.5 c F r}R 0 0 3 c F 3{[-.5 2 1 3 -2 25 4 3]rectfill r}R 0 g 4 L 0 0 11.5 c stroke 1 g 1 L 3{0 15 10 c stroke r}R showpage

Código (versão não compactada):

5 5 scale                  % over-all scale
36 24 translate            % over-all shift

% define some short-named procedures for later use
<<
  /c { 0 360 arc closepath }  % append circle (x, y, radius are taken from stack)
  /r { 120 rotate }           % rotate by 120°
  /R { repeat }
  /L { setlinewidth }
  /g { setgray }
  /F { fill }
>> begin

3 {
    0 11 15 c F       % black circle
    r                 % rotate by 120°
} R
1 g                   % set white color
3 {
    0 15 10.5 c F     % white circle
    r                 % rotate by 120°
} R
0 0 3 c F             % small white circle
3 {
    [ -.5 2 1 3       % white gap near center
      -2 25 4 3       % white gap on edge
    ] rectfill
    r                 % rotate by 120°
} R
0 g                   % set black color
4 L                   % set linewidth 4
0 0 11.5 c stroke     % black ring
1 g                   % set white color
1 L                   % set linewidth 1
3 {
    0 15 10 c stroke  % white ring
    r                 % rotate by 120°
} R
showpage

Resultado (como animação para ver como é desenhado):

resultado

Thomas Fritsch
fonte
Ótima animação.
dana
2

Python 3 com pygame, 327 314 287 278 bytes

(Aplicamos vários hacks desagradáveis ​​para economizar 13 bytes; principalmente não mais armazenando a cor, mas calculando-a rapidamente -(r>25))
(Refatorada para funcionar, perdendo sys; hackeada mathem favor de constantes de coordenadas; pequenos ajustes; salvos 27 bytes)
(Reescrever coordenadas constantes para truques matemáticos complexos para obter (co) seno , economizando 9 bytes)

Função que usa um único argumento inteiro representando metade da largura / altura da imagem resultante. Por exemplo f(500), criará uma janela de 1000 x 1000 pixels e desenhará um símbolo de risco biológico.

from pygame import*;D=display
def f(S):
 u=D.set_mode([S*2]*2);b=S>>6
 for p,r,w in(22,30,0),(30,20,0),(0,27,7),(30,21,2),(0,6,0),(51,4,0):
  for l in 0,4/3,8/3:Z=1j**l*p*b;q=S+int(Z.imag),S-int(Z.real);draw.circle(u,-(r>25),q,r*b,w*b);r-20or draw.line(u,0,(S,S),q,b*2);D.flip()

Versão não abreviada:

import pygame
import math
import sys

size = int(sys.argv[1])
basic = size // 55

screen = pygame.display.set_mode((size * 2, size * 2))

circles = [
    (22, 30, 0, -1),  # basic shape
    (30, 20, 0, 0),   # large cutouts
    (0, 27, 7, -1),   # "background circle"
    (30, 21, 2, 0),   # "background circle" clearance
    (0, 6, 0, 0),     # center disc
    (51, 4, 0, 0),    # blunt the points
]

for pos, radius, width, color in circles:
    for lobe in [0, math.pi * 2 / 3, math.pi * 4 / 3]:
        x = int(math.sin(lobe) * pos * basic) + size
        y = size - int(pos * basic * math.cos(lobe))
        pygame.draw.circle(screen, color, (x, y), radius * basic, width * basic)
        # Hack to draw the small slots in the center
        if radius == 20:
            pygame.draw.line(screen, 0, (size, size), (x, y), basic * 2)

pygame.display.flip()

A chave para este programa é principalmente explorar a simetria de três vias do símbolo e expressar as operações de desenho o mais esparsamente possível. O coração de tudo isso é circles, que é uma lista de definições de círculo, consistindo apenas em:

  • position: a que distância da origem em meias unidades básicas
  • radius: o raio do círculo em meias unidades básicas
  • width: a largura da borda do círculo (a partir do círculo externo, 0 = preenchimento)
  • color: explorando o fato de que pygame interpreta 0como preto e -1branco

Cada operação de desenho é repetida três vezes, girada 120 °. O embotamento das "garras" é feito com outro círculo. Os "cortes de linha" internos são especiais, porque eu não conseguia pensar em uma maneira mais eficiente de obtê-los lá. A "unidade básica" definido na especificação é duplicada aqui, então eu não tinha que usar .5no circlese int()em todo o lugar para satisfazer pygame.

Resultado para python3 -c 'from biohazard import *; f(500)':

Exibir a saída desta resposta

marcelm
fonte
11
Bom trabalho e bem-vindo ao CGCC! A descrição deve dizer "Python 3 + pygame" quando uma biblioteca não integrada é usada. A entrada pode ser obtida da entrada padrão ou como um argumento de função para evitar a importação do sysmódulo, que reduz o código (consulte as regras ). Além disso, esse truque pode ser aplicado para evitar a necessidade de importação math.
Joel
@ Joel Obrigado pelo feedback! Incluí pygame no cabeçalho e converti o código em uma função. Quanto a isso math, refatorei isso para uma lista de coordenadas; eram apenas 3 deles de qualquer maneira. Não é necessário (co) seno.
marcelm 8/09
11
A aplicação do truque mencionado acima economiza mais bytes do que colocar todos os números no código-fonte.
Joel
@ Joel Obrigado pelo lembrete; anteriormente, descartei essa opção porque parecia mais longa, mas parece que eu estava errado. Também permitiu mais otimizações.
marcelm 8/09
1

Tcl / Tk - 557 bytes

set F #000
set B #F50
pack [canvas .c -bg $B]
rename expr e
rename foreach f
rename proc p
p R r {list [e $r*cos($::a)] [e $r*sin($::a)]}
p D {d r} {lassign [R $d] x y;list [e $x-$r] [e $y-$r] [e $x+$r] [e $y+$r]}
p C {d r c} {.c cr o {*}[D $d $r] -f $c -outline $c}
p L {p q w} {.c cr l {*}[R $p] {*}[R $q] -w [e $w] -f $::B}
p A {d r w c} {.c cr a {*}[D $d $r] -w [e $w] -star 0 -ex 359.9 -sty arc -outline $c}
f x {{C 11 15 $F} {C 15 10.5 $B} {L 0 5 1} {L 20 40 4} {C 0 3 $B} {A 0 11.75 3.5 $F} {A 15 10 1 $B}} {f a {2.62 4.72 6.81} $x}
.c move all 99 99

Essa versão, no entanto, é chata, pois você obtém a mesma imagem em tamanho pequeno, não importa o quê. Porém, ele satisfaz as condições de OP para exibição na tela. Aqui está a versão não compactada com comentários e a capacidade de especificar um tamanho adicionado em:

# Input: command line argument is the pixel width (same as the height) of the window to create
# For example:
#   wish a.tcl 500
set window_size $argv

set foreground_color #000
set background_color #F50
pack [canvas .c -bg $background_color -width $window_size -height $window_size]

# Helper procs to generate x,y coordinates
proc radius->x,y r {
  list [expr {$r*cos($::angle)}] [expr {$r*sin($::angle)}]
}

proc center_offset,radius->rectangle {offset r} {
  lassign [radius->x,y $offset] x y
  list [expr {$x-$r}] [expr {$y-$r}] [expr {$x+$r}] [expr {$y+$r}]
}

# Tk's canvas does not scale line widths, so we have to do that manually
# The $scale is a global variable for compressing the code text above
set scale [expr {$window_size*.016}]

# These three procs draw items in the canvas
proc circle {offset r color} {
  .c create oval {*}[center_offset,radius->rectangle $offset $r] -fill $color -outline $color
}
proc line {p q w} {
  .c create line {*}[radius->x,y $p] {*}[radius->x,y $q] -width [expr {$::scale*$w}] -fill $::background_color
}
proc annulus {offset r w color} {
  .c create arc {*}[center_offset,radius->rectangle $offset $r] -width [expr {$::scale*$w}] -start 0 -extent 359.9 -style arc -outline $color
}

# Our list of shapes to draw
#  circle  center_offset, radius,                   color
#  line    end_offset_1,  end_offset_2, line_width
#  annulus center_offset, radius,       line_width, color
foreach command {
  {circle  11 15        $foreground_color}
  {circle  15 10.5      $background_color}
  {line     0  5    1}
  {line    20 40    4}
  {circle   0  3        $background_color}
  {annulus  0 11.75 3.5 $foreground_color}
  {annulus 15 10    1   $background_color}
} {
  # Each command gets applied thrice, rotated $angle radians each time
  foreach angle {2.62 4.72 6.81} $command
}

.c scale all 0 0 $scale $scale
.c move all [expr {$window_size/2}] [expr {$window_size/2}]

# Some random convenience stuff for playing with it
bind . <Escape> exit
after 500 {focus -force .}

Desculpe, não há fotos (funcionando hoje no meu telefone). Produz um símbolo preto em um fundo laranja com risco biológico.

Dúthomhas
fonte