Нарисуйте ☣ (символ биологической опасности)

66

Нарисуйте символ биологической опасности в произвольном цвете на ярко окрашенном фоне. Конкретные пропорции были опубликованы в выпуске Федерального реестра правительства США от 27 июня 1974 года .

подробности

  • В качестве вывода разрешены запись в файл (растровые и векторные форматы) или отображение на экране.

  • Вы можете нарисовать только границу или заполненную форму.

  • Если вы используете растровые изображения, вы должны принять параметр (или два) в качестве входных данных, которые позволяют вам регулировать разрешение выходных данных (например, ширина / высота).

  • Фон должен по крайней мере иметь размер ограничительной рамки символа, но может быть больше.

  • Вывод символа юникода ☣ недостаточно .

  • Точные соотношения используемых расстояний приведены на следующей диаграмме (которая изначально была отсюда ):

Я также попытался сделать дополнительную диаграмму с теми же измерениями, которая, надеюсь, будет немного легче читать:

(Навеяно постом на 99% невидимым )

flawr
источник
2
Лазейка: можем ли мы просто поместить изображение размером 1x1 на фоне переменного размера?
Джон Дворжак
Я не думаю, что если вы установите разрешение достаточно большим, символ все равно должен появиться. И в любом случае я надеюсь, что люди здесь имеют достаточно здравого смысла, чтобы понять, что мы имеем в виду :)
flawr
1
Если бы у меня было время, я бы попробовал использовать PostScript или графику черепах.
Гай Кодер
1
@ SriotchilismO'Zaic Длина определяется двумя окружностями: каждый из них имеет заданный центр и радиус, поэтому длина определяется размером зазора.
flawr
1
Это «E» на исходной диаграмме (крестики обозначают центры окружностей) и на том, который я добавил ниже (где радиус соответствует оси симметрии). 11
flawr

Ответы:

96

T-SQL, 442 441 426 355 349 344 байта

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(@)

Сохранено более 70 байт с использованием REPLACE()длинных ключевых слов и выполнением в виде динамического SQL. Посмотрите код после замены на скриншоте ниже.

Я удвоил значения координат из иллюстрации на примере и переместился на 9 единиц вверх, чтобы уменьшить количество отображаемых десятичных знаков.

Это было сделано в SQL 2017 с использованием геопространственных функций, представленных в SQL 2008. Множество полезных встроенных функций геометрии, в том числе STBuffer, что дает мне простой способ определения кругов разных размеров вокруг точки.

Визуальный вывод с аннотированным кодом:

Символ биологической опасности в T-SQL с использованием геопространственных функций

Для большего количества рисунка T-SQL, см. Мой Пасхальный заяц .

Для более практического применения этой технологии в SQL, прочитайте эту статью или посмотрите это видео . У SE даже есть связанный сайт, gis.stackexchange.com .

Редактирование:

  1. Сохраняется 1 байт путем изменения координаты от 104 до 99.
  2. Сохранено 15 байт, взяв STDifferenceодин STUnionиз объектов, а не каждый в отдельности.
  3. Сохранено 71 байт, используя REPLACE()повторяющиеся ключевые слова, а затем выполняется как динамический SQL. Отменено Редактирование 2, чтобы оставить больше замен STDifference.
  4. Сэкономили 4 байта, переместив центр вверх на 9 единиц, что изменило несколько координат на однозначные (отрицательные) цифры. Это также высвободило цифру 5для использования вместо символа замены '#', сохранив еще 2 байта в кавычках.
  5. Сохранено 5 байтов путем перемещения )в STDifferenceстроку замены; спасибо, Николас!
BradC
источник
56
Почему ... это существует?
Александр
26
@ Александр Для баз данных, которые содержат или используют географические данные, такие как перепись населения, научные исследования или даже продажи клиентов по географическим регионам. Или просто для рисования кроликов и символов биологической опасности.
BradC
24
SQL достаточно плох для того, для чего он предназначен, кто в здравом уме хотел бы пойти дальше. Представьте GUI, написанные на SQL. Мне нужны аннотации, аспекты и структура модульного тестирования. Нам нужно идти deeeeeper .
Александр
24
@ Александр Как пожелаете: TSQLT
FreeMan
15
@FreeMan Ох, боже ...
Александр
32

Tex + Tikz, 232 байта

43 байта сохранены при переключении на текс. Спасибо Фелипе Олейнику

Некоторые байты сохранены благодаря 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

С разрывами строки и без \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

объяснение

Это немного устарело, я исправлю это, когда смогу выяснить, как сделать изображения не слишком привлекательными

Здесь я собираюсь объяснить, как несжатый ответ решает проблему. Я могу в какой-то момент объяснить, как работает сжатие. Сначала мы рисуем большие черные круги:

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

введите описание изображения здесь

Затем мы рисуем несколько белых линий:

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

введите описание изображения здесь

Затем мы рисуем белые кружки:

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

введите описание изображения здесь

Затем мы добавляем центральный белый круг:

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

введите описание изображения здесь

Затем мы добавляем черное кольцо:

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

введите описание изображения здесь

Затем мы удаляем части черного кольца

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

введите описание изображения здесь

Мастер пшеницы
источник
9
Вы не притупили шесть внешних точек. Между каждой парой должно быть 4 единицы белого пространства.
Уровень Река St
1
@LevelRiverSt Шесть внешних точек теперь на расстоянии 4 единиц от своего партнера.
Мастер пшеницы
2
Эти «кончики когтей» слишком острые, они должны состоять из отрезков прямых линий, параллельных отрезкам, идущим от центрального круга. Также 20.88 выглядит довольно подозрительно.
flawr
Вы можете сохранить другой байт, используя \1вместо \x, как вы можете затем использовать \def\f{\foreach\1in{90,210,330}}.
Skillmon
1
@ flawr хорошо ... теперь они буквально немного меньше, чем 5000x5000 ... только 90x90 сейчас ... едва ли можно разобрать детали: D
Нельсон
15

C 8010 байт

Еще до SVG или EMF вам приходилось иметь дело с растром, и если вы хотели, чтобы что-то загружалось сразу, скажем, до того, как O / S был готов, например, экран запуска Windows, вы должны были использовать RLE или длину выполнения -encoding. Этот монстр выводит файл PBM, используя RLE в качестве данных. Стройте как обычно и бегите вот так ./biohazard > biohazard.pbm.

Если бы вы включили все фреймворки, необходимые для генерации, например, движок SVG в HTML, библиотеки Java и т. Д., Это, вероятно, было бы наименьшим автономным решением , поскольку putsэто единственная внешняя функция и, как правило, одна из наименьших stdio.hфункции.

Относительно этой детали:

Если вы используете растровые изображения, вы должны принять параметр (или два) в качестве входных данных, которые позволяют вам регулировать разрешение выходных данных (например, ширина / высота).

Я интерпретировал «должен» как отличающийся от «должен», например, как в RFC 2119 , поэтому я не включил масштабирование, потому что для этого кода было бы возможно только сделать кратные оригиналу, например, ./biohazard 2и это представило бы atoi, printfи другие осложнения, которые отвлекают от основной цели представления.

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
источник
1
Было бы неплохо объяснить, как вы сгенерировали код.
Кер
Код выводит новую строку после каждого символа; Я думаю, что вам нужно putchar()или подобное.
marcelm
@marcelm - формат PBM P1 в порядке!
1
Я почти уверен, что это должно означать необходимость в этом вопросе, но это, вероятно, стоило бы обсудить с ОП.
Пшеничный волшебник
1
Я не думаю, что использование должно обязательно означать, что есть различие. Это действительно вопрос, который вы должны (или, возможно, должны) задать ОП.
Мастер пшеницы
15

TeX + Ti k Z, 234 230 226 байт

Первоначально на 5 байтов длиннее, чем ответ Шриотчилизма О'Зайча , но этот должен быть правильным. Это похоже на его ответ, но здесь и там сохраняется еще несколько байтов, ему нужен еще один \draw[line width=8](в приведенном ниже коде это сделано \28](~30)to(~55);, то есть только 17 байтов, добавленных только для этого), чтобы получить правильные кончики символа, следовательно, 5 байтов больше общая длина кода.

И благодаря Sriotchilism O'Zaic я перечитал некоторые вопросы и понял, что могу изменить цвет на красный, чтобы снова сэкономить несколько байт:

\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 байт

Просто, если кому-то все равно, следующий использует основанный на TeX диалект гольф-кода, над которым я работаю (не считайте код стабильным). Число байтов включает символы EOL и символ EOF, так как они используются семантически (EOL разделяет аргументы циклов). До сих пор диалект довольно мал и содержит только короткие сокращения для определений и синтаксис цикла for, однако он специально не написан для этого ответа, поэтому он не должен нарушать правила игры в код. Репозиторий для -g.tex-package / file: 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);
}

Вывод обоих фрагментов кода выглядит одинаково:

введите описание изображения здесь

( лень обновлять изображение, просто представьте, что оно красное )

Skillmon
источник
Мой ответ теперь правильный и на 2 байта короче вашего. Я уверен, что кто-то мог бы объединить некоторые из моих ответов с некоторыми из ваших, чтобы сделать более короткий, но я не совсем понимаю ваш ответ.
Пшеничный волшебник
@ SriotchilismO'Zaic, если я изменю цвет на красный (переопределив правило, что цвет может быть произвольным), я получу его до 230 байт.
Skillmon
@ SriotchilismO'Zaic, и, очевидно, вы сэкономили больше, чем один байт в своем ответе, посмотрев на мой (просто сказав).
Skillmon
Хорошо, я посмотрел на твой ответ и не понял, что он делает, поэтому я не думаю, что мог бы действительно очень многое почерпнуть из твоего ответа. Но я изменил сообщение, чтобы удалить точное число в любом случае, так как, возможно, я взял некоторые вещи из вашего ответа, не осознавая этого.
Пшеничный волшебник
2
@ SriotchilismO'Zaic все в порядке. В конце концов, на мой код влияет ваш код, в настоящее время я пытаюсь написать пакет для игры в гольф, чтобы превратить TeX в какой-то язык для игры в код. Когда я наконец опубликую его, мой ответ будет короче :) (Это не язык, специально разработанный для этого вопроса, поэтому он не нарушает правила)
Skillmon
12

GLSL, 700 629 564 545 499 байт

#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.;}

Я играл с Shadertoy, поэтому я попробовал язык затенения GLSL. Код просто растеризует круги и линии, проверяя каждый фрагмент, и присваивает им значение один или ноль. Размер был сокращен с> 1000 байт при интенсивном использовании макросов.

Шадерой программа

введите описание изображения здесь

Roninkoi
источник
1
Добро пожаловать на сайт! Аккуратный первый ответ!
Пшеничный волшебник
Я не знаю языка, но может &&и ||быть golfed к &и |в некоторых или во всех частях?
Кевин Круйссен
@KevinCruijssen Это подмножество C, так что это будут побитовые операции. Для меня компилятор жалуется на тип, хотя
Roninkoi
1
@Roninkoi Я действительно видел, что он был основан на C. В C можно использовать |/ &вместо ||/ &&для bools, не так ли? Давно ничего не делал в Си, так что не уверен. Я знаю, что это работает в Java / C # .NET в большинстве случаев. Но я только сейчас заметил добавленную вами ссылку на Shadertoy, и она, похоже, не работает там, как вы уже заявили. Ах хорошо. Хороший первый ответ, кстати! Добро пожаловать в CGCC.
Кевин Круйссен
Я сократил -30 байт в размещенном коде, но заголовок имеет 566 байт, а отправленный код - 628?
PrincePolka
12

SVG (HTML5), 434 410 321 байт

<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

Теперь на основе SVG @ LevelRiverSt.

Нил
источник
1
Я считаю, что опускание <defs>безопасно. Это работает для меня на Firefox, Chrome и Edge.
Арно
@Arnauld Спасибо, значит я тоже могу избавиться от первого <use>!
Нил
12

Обработка, 371 368 байт

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

Я не был уверен, должен ли Processing считаться растеризованным или нет для целей этой задачи. Если он считается растеризованным, то translateи scaleнеобходимо сделать символ разборчивым и отображаемым на экране для данного размера окна. Но, поскольку все команды рисования векторизованы, это работает в любом заданном масштабе; так что если мы предположим, что рисование в относительном начале шириной около 200 единиц - это нормально, первые 43 байта могут быть отброшены.

Предполагается, что цвет фона - 204, 204, 204это цвет фона по умолчанию при обработке. Оно также предполагает rectModeиз CORNERи ellipseModeиз CENTER(по умолчанию)

С начальным size(640, 640)результатом результирующий эскиз выглядит так:

введите описание изображения здесь

Удвоив масштаб, я сохранил 3 байта, потому что .5исключены s (хотя несколько чисел действительно переходят от 1 до 2 цифр).

Конструкция аналогична решению TeX: черный, а затем серый сверху «стирают» промежутки между формой.

Объяснение:

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);
}
Кертис Феннер
источник
Выглядит хорошо :) Я думаю, что если удвоить все измерения, вы можете избежать .5!
flawr
Да, но это также изменит однозначное число на двузначное, поэтому я не уверен, как оно уравновешивается. Если бы я считал правильно, похоже, что это сэкономит 2 байта. Я также думал об использовании a, scaleчтобы изменить его только для части кода, но не знал, где его лучше всего использовать
Кертис Феннер,
о, ты прав, я не учел это.
flawr
Удвоение измерений для удаления десятичных дробей позволило сэкономить почти 10 байт в моем ответе, хотя несколько координат перешли от однозначных к двузначным. В любом случае, стоит попробовать.
BradC
1
Я сэкономил 3 байта, удвоив масштаб, на котором он нарисован. @IsmaelMiguel
Кертис Феннер
9

GLSL, 319 310 байтов

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

Это можно сделать на Шадертой .

образец

Вы можете использовать симметрию на изображении, чтобы нарисовать его с меньшим количеством отдельных фигур.

Вот несколько завышенная версия:

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

(спасибо @Kevin Cruijssen за удаление ненужных пробелов)

Roeland
источник
1
Вы можете удалить некоторые из пробелов. Тот, что в вашем определении: H(y) sqrtH(y)sqrt; все пробелы в ваших операторах if: if (if(; и те в вашем последнем if-утверждении, окружающем AND: if (R>.10 && R<.135 && S<.095)c=1.;if(R>.10&&R<.135&&S<.095)c=1.;.
Кевин Круйссен
8

HTML / JS,  448 435 433  387 байт

Сохранено много байтов с помощью предварительно свернутой версии SVG @ Neil.
Сохранено 2 байта благодаря @Shaggy

Сжатая версия этого SVG-файла из 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>

Попробуйте онлайн! (просто выводит распакованную строку)

Демонстрационный фрагмент

Arnauld
источник
Это работает на CodePen в Chrome Android для 392.
Shaggy
1
@Arnauld Я перевернул свой ответ, хотя он стоил 5 байт (хотя я нашел еще один ненужный байт, поэтому в целом мой результат увеличился только на 4).
Нил
@Neil Обновлено соответственно. ;)
Арно
Оказывается, SVG @ LevelRiverSt намного меньше!
Нил
7

Haskell , 530 491 436 435 430 420 байтов

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]

Выводит файл PBM.

Это было очень весело!

Биологическая опасность

(Я должен был преобразовать это в PNG, чтобы загрузить в imgur)

По сути, мы создаем наши собственные функции векторной графики, которые визуализируют изображение пиксель за пикселем, определяя, является ли пиксель частью фигуры. Форма построена в виде группы кругов и линий (исходящих из источника), соединенных с основными операциями над множествами: объединение, пересечение и нет. Круги состоят из их центра и радиуса, а линии имеют минимальный радиус, ширину и угол в этом порядке. Обнаружить членство в круге легко: я просто вычитаю координаты центра и сравниваю величину с радиусом. Линия немного сложнее: я поворачиваю точку на противоположный угол, чтобы привести ее (чтобы свести на нет поворот), а затем просто проверяю, попадают ли координаты x и y в ожидаемый диапазон. Минимальный радиус должен обеспечивать, чтобы больший зазор на дальних концах больших кругов не перекрывал маленькие зазоры вблизи центра. После этого просто установить булеву логику для установки математики.

РЕДАКТИРОВАТЬ: Большое спасибо @flawr за удаление 39 байтов!

EDIT2: Большое спасибо @Christian Sievers за удаление 55 байтов! Хорошая идея превратить их в функции

EDIT3: Еще раз спасибо @Christian Sievers за то, что сбрил еще один байт!

РЕДАКТИРОВАТЬ 4: Удалил 7 байтов благодаря @ H.PWiz и @Angs!

EDIT5: только что заметил ошибку! Я рендерил линии в два раза толще, чем они должны были быть! Чтобы исправить это, мне понадобилось 2 байта (пришлось разделить ширину на 2; мог бы скорректировать постоянные значения, но изменение 1 на 0,5 также стоило бы 2).

EDIT6: Спасибо @Angs за удаление еще 10 байтов!

user1472751
источник
Вау, это так круто. Редко можно увидеть, что кто-то определяет свои собственные типы в код-гольфе здесь :) Два вопроса: нужно ли иметь отрицательные углы [-90,-210,-330]? И это было бы возможно изменить <=до <?
flawr
1
Так что я попробовал это и сумел сбрить несколько байтов
flawr
1
О, если вы не знали, у нас есть чат на Haskell, а также несколько советов по игре в гольф на Haskell .
flawr
1
Еще один небольшой
твик
1
Приятно! Это возможно без типа данных
Кристиан Сиверс
6

Рубин , 278 байт

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})'/>"}

Попробуйте онлайн!

Создает приведенный ниже код SVG с символом 200% шкалы в OP.

Он состоит из круга сзади и зубцов на переднем плане. Зубец масштабируется -1,0,1по Xоси и поворачивается на кратные 120 градусов. Случаи, когда Xмасштабирование равно нулю, не выводят, а -1и +1. предоставьте две стороны каждой пары зубцов.

Использование сделано из широкой белой каймы 2 блока вокруг зубца отрезать заднюю окружность, используя strokeи stroke-widthатрибуты. Чтобы внутренняя форма соответствовала ОП, координаты перемещаются на 1 единицу (на половину ширины границы.) Обратите внимание, что путь намеренно не закрыт, чтобы подавить рисование последней линии границы. Это обеспечивает объединение двух половинок каждой пары зубцов.

90 градусов внутреннего круга нарисованы, а не ожидаемые 60, по соображениям игры в гольф. Это означает, что между основаниями каждой пары зубцов есть некоторое перекрытие, но это не влияет на внешний вид выходной формы.

<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)'/>

Уровень реки St
источник
6

PostScript , 367 359 328 271 байт

Код (сжатая версия):

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

Код (несжатый вариант):

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

Результат (как анимация, чтобы увидеть, как он нарисован):

результат

Томас Фрич
источник
Отличная анимация.
Дана
2

Python 3 с pygame, 327 314 287 278 байт

(Применены различные мерзкие хаки для сохранения 13 байт; в первую очередь больше не хранится цвет, а вычисляется его на лету -(r>25))
(Рефакторинг для функции, потеря sys; взломан mathв пользу констант координат; небольшие изменения; сохранены 27 байтов)
(Переписана координата) константы для сложных математических трюков, чтобы получить (со) синус , экономя 9 байтов)

Функция, которая принимает один целочисленный аргумент, представляющий половину ширины / высоты результирующего изображения. Например f(500), создаст окно размером 1000x1000 пикселей и нарисует там символ биологической опасности.

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

Несокращенная версия:

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

Ключом к этой программе является в основном использование симметрии символа с 3 точками и как можно более редкое выражение операций рисования. Сердцем всего circlesэтого является список определений кругов, состоящий только из:

  • position: как далеко от начала отсчета в половине основных единиц
  • radius: радиус круга в половине основных единиц
  • width: ширина границы круга (внутрь от внешнего круга, 0 = заполнить)
  • color: используя тот факт, что Pygame интерпретирует 0как черный и -1как белый

Каждая операция рисования повторяется три раза, повернутая на 120 °. Затупление "когтей" делается с помощью другого круга. Внутренние «линии разрезов» имеют специальный корпус, потому что я не мог придумать более эффективный способ их доставки. «Основная единица» определена в спецификации удваивается здесь , так что я не должен использовать .5в circlesи int()повсюду , чтобы удовлетворить Pygame.

Результат для python3 -c 'from biohazard import *; f(500)':

Показать вывод этого ответа

marcelm
источник
1
Хорошая работа и добро пожаловать в CGCC! В описании должно быть написано «Python 3 + pygame», когда используется не встроенная библиотека. Ввод может быть взят из стандартного ввода или в качестве аргумента функции, чтобы избежать импорта sysмодуля, что сокращает код (см. Правила ). Кроме того, этот трюк может быть применен, чтобы избежать необходимости импорта math.
Джоэл
@Joel Спасибо за отзыв! Я включил pygame в заголовок и преобразовал код в функцию. Что касается math, я реорганизовал это в список координат; в любом случае их было всего 3. Нет (со) синус необходим.
marcelm
1
Применение вышеупомянутого трюка на самом деле экономит больше байтов, чем помещение всех чисел в исходный код.
Джоэл
@Joel Спасибо за напоминание; раньше я отказался от этого варианта, потому что он казался длиннее, но, похоже, я ошибался. Это также позволило еще несколько оптимизаций.
marcelm
1

Tcl / Tk - 557 байт

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

Однако эта версия скучна, поскольку вы получаете одно и то же изображение небольшого размера, несмотря ни на что. Однако он удовлетворяет условиям OP для отображения на экране. Вот несжатая версия с комментариями и возможностью указать размер, добавленный в:

# 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 .}

Извините, фотографий нет (работаю сегодня на телефоне). Создает черный символ на биологически опасном оранжевом фоне.

Dúthomhas
источник