47
\$\begingroup\$

Draw the ionising-radiation-hazard-symbol in an arbitrary colour on a distinctly coloured background. The specific proportions were published in the June 27th 1974 issue of the Federal Register of the US Government.

Details

  • As output, writing to a file (raster and vector formats are permitted) or displaying on the screen are both allowed.

  • You can draw just the border or the filled shape.

  • If you use raster images, you should take a parameter (or two) as input that lets you adjust the resolution of the output (e.g. width/height).

  • The background must at least have the size of the bounding box of the symbol but may be larger.

  • Outputting the unicode symbol ☢ is not sufficient.

  • The exact ratios of the used distances are given in following diagram (which was originally from here):

Related: Draw the ☣ (Biohazard Symbol)

\$\endgroup\$
10
  • \$\begingroup\$ Can I take an input n such that the image has width 2*n+1? \$\endgroup\$
    – Luis Mendo
    Commented Nov 23, 2019 at 18:50
  • \$\begingroup\$ @LuisMendo Sure! \$\endgroup\$
    – flawr
    Commented Nov 23, 2019 at 19:42
  • 1
    \$\begingroup\$ Is it ok to return an integer matrix of 0s and 1s as the representation of the bitmap image? \$\endgroup\$ Commented Nov 23, 2019 at 21:36
  • 2
    \$\begingroup\$ @NickKennedy I'd say a matrix just as a data type is not enough, but if it is printed nicely with two different characters as the "colours" (and no separators in between) it should be ok. \$\endgroup\$
    – flawr
    Commented Nov 24, 2019 at 8:37
  • 1
    \$\begingroup\$ @mypronounismonicareinstate I added the twos suggestions in the "defaults for IO" on meta, please vote. (1) (2) \$\endgroup\$
    – flawr
    Commented Nov 24, 2019 at 9:43

37 Answers 37

41
\$\begingroup\$

BBC BASIC, 200 bytes

f=500
g=1/SQR(3)
CIRCLE FILLf,f,f
GCOL15
MOVE-100,f
MOVEf,f
PLOT85,f*(1-g),0
MOVE1100,f
MOVEf,f
PLOT85,f*(1+g),0
MOVEf*(1-g),2*f
MOVEf,f
PLOT85,f*(1+g),2*f
CIRCLE FILLf,f,150
GCOL0
CIRCLE FILLf,f,100

Somehow outgolfing Python, this works by drawing a large black circle, filling in the white triangular sections, drawing a central white circle and finally drawing the central black circle.

\$\endgroup\$
2
  • 25
    \$\begingroup\$ I guess you couldn't resist answering this challenge! \$\endgroup\$
    – Neil
    Commented Nov 24, 2019 at 0:48
  • 13
    \$\begingroup\$ -1 I'm sure you are using insider knowledge! \$\endgroup\$
    – flawr
    Commented Nov 25, 2019 at 10:22
20
\$\begingroup\$

MATL, 46 44 41 bytes

:t_0vSt!Yy1MZ;3*YP/koyG.3*>*yG<*wG5/<=3YG

Given an input n, the image has width 2*n+1 in pixels.

Try it at MATL Online!

Explanation

:       % Implicit input n. Range [1 ... n]
t_      % Duplicate, negate. Gives [-1 ... -n]
0       % Push 0
v       % Concatenate stack as a column vector: [1; ...; n; -1; ...; -n; 0]
S       % Sort. Gives [-n; -n+1; ... n]
t!      % Duplicate, transpose. Gives the row vector [-n -n+1 ... n]
Yy      % Hypotenuse, with implicit expansion. Gives a matrix containing radius
        % for all points in a grid from -n to -n
1M      % Push the two inputs of the last function, again
Z;      % atan2, with implicit expansion. Gives a matrix containing angle between
        % -pi and pi, where 0 is real positive semiaxis
3*YP/k  % Multiply by 3, divide by pi, round down. Gives an integer for each sextant
o       % Parity. This assigns 0 and 1 alternately to points in different sextants.
        % See this partial result as IMAGE 1 below.
y       % Duplicate from below: pushes the matrix of radii again
G.3*>   % Greater than 0.3*n?, element-wise. Gives 0 or 1 for each entry. This
        % realizes the "1.5R" circle from the specification. See IMAGE 2
*       % Multiply, element-wise. See IMAGE 3
y       % Duplicate from below: pushes the matrix of radii again
G<      % Less than n?, element-wise. Gives 0 or 1 for each entry. This realizes
        % the "5R" circle from the specification. See IMAGE 4
*       % Multiply, element-wise. See IMAGE 5
w       % Swap: pushes the original matrix of radii to the top
G5/<    % Mess than 0.2*n? This realizes the "R" circle in the spec. See IMAGE 6
=       % Equal?, element-wise. This combines the two matrices so far to produce
        % the final result, with 0 for foreground pixels and 1 for background pixels.
        % See IMAGE 7
3YG     % Show image. 0 is displayed as black, 1 as white

Intermediate results. 0 is shown as black, 1 as white:

  • Image 1:

enter image description here

  • Image 2:

enter image description here

  • Image 3:

enter image description here

  • Image 4:

enter image description here

  • Image 5:

enter image description here

  • Image 6:

enter image description here

  • Image 7 (final result):

enter image description here

\$\endgroup\$
18
\$\begingroup\$

SVG(HTML5), 175 bytes

<svg viewBox=-24,-24,48,48><circle r=4 /><path id=b d=M3,-5.2A6,6,0,0,1,6,0H20A20,20,0,0,0,10,-17.32z /><use href=#b transform=rotate(120) /><use href=#b transform=rotate(240)

Originally based on @Arnauld's answer, but removes unnecessary characters, scales the numbers by 80% to make them golfier, and draws the curved section's lines in a different order so that I can use an H instead of an L.

\$\endgroup\$
5
  • \$\begingroup\$ I only get one of the three outer parts, in data:text/html (Chrome 78.0.3904.106), oddly enough \$\endgroup\$
    – rydwolf
    Commented Nov 23, 2019 at 21:49
  • \$\begingroup\$ @RedwolfPrograms Hmm... I get one only if I forget to escape the # as %23, although I only get all three if I append a >... \$\endgroup\$
    – Neil
    Commented Nov 24, 2019 at 0:45
  • \$\begingroup\$ I see you and I raise you ;). 128 bytes - see here \$\endgroup\$
    – G0BLiN
    Commented Nov 24, 2019 at 16:46
  • \$\begingroup\$ @G0BLiN Very clever - similar to the BBC BASIC solution I guess? \$\endgroup\$
    – Neil
    Commented Nov 24, 2019 at 21:50
  • \$\begingroup\$ @Neil - I admit I didn't read the details of that answer until you've pointed it out, but yes - that's the exact approach Beta Decay used there - I just felt that there's aught to be a better way than writing use href=#b transform=rotate(120) twice... \$\endgroup\$
    – G0BLiN
    Commented Nov 26, 2019 at 12:51
18
\$\begingroup\$

SVG(HTML5), 128 126 124 120 bytes

(Thanks Wheat Wizard for saving 2 bytes by using .2 rather than 0.2)
(Drawing triangles from right to left saves 2 bytes)
(Thanks Grimmy for saving 2 bytes by using a modified path)
(And reduced another 2 bytes by using a different starting point on the path)

 <svg viewbox=-2,-2,4,4>
  <circle r=1 />
  <circle r=.3 fill=#FFF />
  <path d=m2,3.4V0h-4v3.4l4,-6.8h-4 fill=#FFF />
  <circle r=.2

<svg viewbox=-2,-2,4,4><circle r=1 /><circle r=.3 fill=#FFF /><path d=m2,3.4V0h-4v3.4l4,-6.8h-4 fill=#FFF /><circle r=.2

Rather than basing the SVG on wikipedia's vector image - which is drawn in a reasonable way, this solution draws:

  1. A black large circle <circle r=1 />
  2. A smaller white circle <circle r=.3 fill=#FFF />
  3. Three white triangles as a single continuous path <path d=m2,3.4V0h-4v3.4l4,-6.8h-4 fill=#FFF />
  4. And a small black circle <circle r=.2

Taking advantage of modern browsers forgiving interpretation which ignores unclosed tags (saved the final 9 bytes of /></svg> )

This is the result:

SVG output

And this is the same code with the path in yellow to demonstrate what's going on: enter image description here

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Welcome to the site! This is not rendering the small black circle on my browser (firefox). Even if I add the /><svg> \$\endgroup\$
    – Wheat Wizard
    Commented Nov 24, 2019 at 17:07
  • 1
    \$\begingroup\$ I just tested on chrome as well and it doesn't seem to work there. For the record it is fine if it only works in a specific browser (you should indicate which in your question so it can be tested). I just want to make sure you haven't made an accident. \$\endgroup\$
    – Wheat Wizard
    Commented Nov 24, 2019 at 17:09
  • 1
    \$\begingroup\$ Thanks. That snippet does work for me. And since I can now test it I can confirm that both 0.2 and 0.3 can have the 0 removed to save two bytes. Could you also include the exact code without the extra whitespace? It is fine to add the whitespace for readability but since whitespace does matter it is always best to include the code you are scoring. \$\endgroup\$
    – Wheat Wizard
    Commented Nov 24, 2019 at 21:50
  • 1
    \$\begingroup\$ l-1,1.7 can be L1,1.7 for -1 byte. \$\endgroup\$
    – Grimmy
    Commented Nov 25, 2019 at 12:50
  • 1
    \$\begingroup\$ d=m2,0h-4v3.4l4,-6.8h-4l4,6.8 saves another two bytes. \$\endgroup\$
    – Grimmy
    Commented Nov 26, 2019 at 13:40
17
\$\begingroup\$

Jelly, 42 bytes

÷ÆṬ÷ØPḂ×3ḞḂ
æịA©>5,1.5aç^/o®Ị¤
×5ŒR÷µçþAZY

Try it online!

A full program that takes an integer n that determines the radius of the central circle and implicitly outputs to STDOUT a \$10n+1\$ square with the desired image encoded as 1 for black and 0 for white.

Per @flawr, this is a permitted output format. Note also that this is effectively a PBM file without the header. Adding P1 L L to the start (where L is replaced by \$10n+1\$) would make it a valid PBM file. Ta

Explanation

Helper link 2

Dyadic link taking y coordinate as left and x as right argument; returns whether the angle is within the filled outer area

÷           | Divide (y by x)
 ÆṬ         | Arc-tangent
   ֯P      | Divide by pi
      Ḃ     | Mod 2
       ×3   | Times 3
         Ḟ  | Floor
          Ḃ | Mod 2

Helper link 1

Dyadic link taking y coordinate as left and x as right argument

æị                 | Convert to complex
  A                | Absolute (i.e. distance from origin)
   ©               | Copy to register
    >5,1.5         | Greater than 5,1.5 (vectorises, so will give two booleans)
          a        | Logical and with:
           ç       | - Result of helper link 2 applied to the input of this link
            ^/     | Reduce using exclusive or
              o  ¤ | Or following as a nilad:
               ®   | Value in register
                Ị  | Absolute of this <= 1

Main link

×5         | Times 5
  ŒR       | Range from -this to +this
    ÷      | Divide by input
     µ     | Start a new monadic chain
      çþ   | Outer table using helper link 1 and:
        A  | - Absolute of the range as the right argument
         Z | Transpose rows and columns

Sample image for n=5

sample

\$\endgroup\$
4
  • \$\begingroup\$ Again, those are characters not bytes. \$\endgroup\$
    – DomQ
    Commented Nov 26, 2019 at 11:20
  • 10
    \$\begingroup\$ @DomQ what do you mean? If you’re discussing the scoring for code golf, the established standard on this site is to use language specific encodings where they exist. Jelly has its own 256 character code page linked to through the Jelly header on my answer. I note a couple of my answers including this one were downvoted recently; if that was you and it was for this reason, I’d respectfully ask you to reconsider since this is the way this SE site has agreed to function. \$\endgroup\$ Commented Nov 26, 2019 at 11:27
  • \$\begingroup\$ ah well, I didn't know that. (But I didn't downvote either.) \$\endgroup\$
    – DomQ
    Commented Nov 26, 2019 at 18:42
  • \$\begingroup\$ @DomQ As per my previous comment, there are a number of languages used regularly here that have single byte encodings with their own codepage. These include 05AB1E, Jelly, APL, Charcoal, Stax. The accepted standard for scoring them is to score them based on bytes <b>in their own codepage</b>. It is possible to have a 42 byte file, pass it to the Jelly interpreter and get the output above. Note these code pages are part of the language. In general, inventing a codepage for a specific answer (i.e. with knowledge of the question) is not so acceptable. There are also posts on meta about this. \$\endgroup\$ Commented Nov 26, 2019 at 18:46
14
\$\begingroup\$

JavaScript (ES7),  118 113 98  93 bytes

Saved 15 bytes thanks to @tsh!

Takes a parameter \$w\$ as input and draws an ASCII art of width \$2w-1\$ and height \$2w\$, using 0 and 1 for the 'pixels'.

f=(x,w=y=x)=>y+w?(--x+w?(r=x*x+y*y,4*x*x>r^y<0?1019:3)>>r**.5/w*10&1:(x=w,y--,`
`))+f(x,w):''

Try it online!

How?

We compute the squared distance from the center:

$$r=x^2+y^2$$

We use \$\sqrt{r}\$ to quantize the distance from the center into 10 bins of width \$w\$:

$$\left\lfloor\frac{10\sqrt{r}}{w}\right\rfloor$$

We use \$r\$, \$x\$ and \$y\$ to determine in which kind of sector we are:

$$(4x^2>r)\text{ xor }(y<0)$$

See this graph!

We turn the above result into a drawing bit-mask, as summarized in the following schema:

schema

Hence the value of the pixel at \$(x,y)\$:

(
  r = x * x + y * y,
  4 * x * x > r ^ y < 0 ?
    1019
  :
    3
)
>> r ** 0.5 / w * 10
& 1
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Maybe you can use the fact that \$ \sin30^{\circ} = \frac 1 2 \$. it could be 105 bytes \$\endgroup\$
    – tsh
    Commented Nov 25, 2019 at 11:24
  • 5
    \$\begingroup\$ And removing Math, it is 98 bytes \$\endgroup\$
    – tsh
    Commented Nov 25, 2019 at 11:31
  • 1
    \$\begingroup\$ @tsh This is brilliant! \$\endgroup\$
    – Arnauld
    Commented Nov 25, 2019 at 11:39
14
\$\begingroup\$

Google Sheets, 277 bytes

=ARRAYFORMULA((POW(COLUMN(A1:CV99)-5*A1,2)+POW(ROW(A1:CV99)-5*A1,2)<A1*A1)+(POW(COLUMN(A1:CV99)-5*A1,2)+POW(ROW(A1:CV99)-5*A1,2)>9/4*A1*A1)*(POW(COLUMN(A1:CV99)-5*A1,2)+POW(ROW(A1:CV99)-5*A1,2)<25*A1*A1)*IFERROR((MOD(3*ATAN2(COLUMN(A1:CV99)-5*A1,ROW(A1:CV99)-5*A1)/PI(),2)<1),0

Creates a grid of 1s and 0s which can be coloured using a conditional format. It takes input in cell A1 as the value of R.

Here's a link.

enter image description here

\$\endgroup\$
9
\$\begingroup\$

HTML / SVG,  201  189 bytes

A revamped version of this file from Wikimedia Commons.

<svg viewBox=-30,-30,60,60><circle r=5 /><path id=b d=M7.5,0A7.5,7.5,0,0,0,3.7,-6.5L12.5,-21.6A25,25,0,0,1,25,0z /><use href=#b transform=rotate(120) /><use href=#b transform=rotate(240) />

\$\endgroup\$
2
  • \$\begingroup\$ 175 bytes: <svg viewBox=-24,-24,48,48><circle r=4 /><path id=b d=M3,-5.2A6,6,0,0,1,6,0H20A20,20,0,0,0,10,-17.32z /><use href=#b transform=rotate(120) /><use href=#b transform=rotate(240) \$\endgroup\$
    – Neil
    Commented Nov 23, 2019 at 18:40
  • 2
    \$\begingroup\$ @Neil You've basically done all the job here, so feel free to post it as your own answer. \$\endgroup\$
    – Arnauld
    Commented Nov 23, 2019 at 18:41
8
\$\begingroup\$

Runic Enchantments, 216 bytes

D::i</~1-:0)?;{:}ak$2?X2    8?1]$#'~~\1?7 c?1$ '~~\?3  L
R:0)?/1-:̹{2,::}}-S{-2pS2p+'qA:{5,:}≮?/:}3,2*S:}S≯?/5,)?/]:̹{2,:}-S{-:̹'-A}'-A0)3*?P2?Z0]{{S:0)a*?:0(4*?~~10,'|A'aA{0)?S-:0≮4*?P2*+3*2P*%P)4*?'#2?' $]

Try it online!

Dear god. Why.
So much went wrong.
It makes me cry.

Several major impediments that ended up making this both (a) a nearly unreadable mess and (b) frustratingly difficult.

The first problem was the fact that Runic doesn't have atan2(x,y), so I had to heckin' work that out myself. And oh yeah, make sure its reasonably golfed, it had to be dropped into an existing program with no alterations, so in-line conditional logic was preferable.

The second problem was that I had a weird issue where I'd multiply the tangent value by 3, modulo to 2pi and get...nonsense. What even is that? Why is it not using angular values? Turned out I had a stray extra value at the bottom of the stack that was throwing the math off. Whoops.

THEN
AND THEN
The program would just suddenly die after the first four bytes of the outer wedges. Oh my, what fun we had. Lets simplify, shall we? Lets just isolate the inputs at that point and... oh. It works fine.

I.

Uh.

Hmm.

When in doubt, check the source code. Can you spot the difference?

Yep. Integer values are totes allowed to divide by zero (and return infinity) and doubles aren't. Oh and that's not even true in the original Unity C# code (which I use as a graphical debugger) as it was an intentional design decision to terminate on div-by-zero.

Wot. Also, conversion to float instead of double for no reason. Just sittin' there.

(╯°Д°)╯︵┻━┻

Explanation

I need a drink first.
dook dook
That's better.

D::i<                     Set up the stack, we need a current position (X,Y) and total size. Init all to read value, counting down is easier than counting up.
                          The D here, and the R below it, constitute the main loop entry
R:0)?\1-                  Compare current X against zero, else decrement
     \~1-:0)?;{:}ak$      if zero, decrement Y. If Y is zero, terminate, else return to the D on the first line (there's a lot of skip-over-logic)
:̹ {2,::}}-S{-             dupe the entire stack, then translate origin by 1/2 width
2pS2p+'qA                 square root (x*x+y*y)
:{5,:}≮?\:}3,2*S:}S≯?\    compare that against 1/20th the width and 1.5/20th the width (R and 1.5R)
  ]$#'~~L       $ '~~L    Print # or <space> for the inner circle (and return to D) skip-bypasses omitted
5,)?/                     Compare against 1/10th the width (5R), print a space and return to D 

]:̹ {2,:}-S{-:̹ '-A}'-A0)3*?P2?Z0]{{S:0)a*?:0(4*?~~10,'|A'aA{0)?S-    Dupe the entire stack and compute atan2(x,y)

:0≮4*?P2*+                       Convert negative values to values greater than pi up to 2 pi
          3*2P*%P)4*?'#2?' $]    Multiply by 3, modulo 2pi, compare against pi. Less: print # else print space. Return to R.

Be wary of improperly stacking unicode combining characters. The little ̹ makes the command apply to the stack-of-stacks and ̸ is boolean-not; eg. is "not less than (aka greater-equals)." Looks like it costs bytes, but because of the upper line, there's a byte savings in that line being shorter, which pays for the +1 byte cost for an extended character in the lower line (typically assuming that the lower line could be ?!/ instead of ?/).

\$\endgroup\$
8
\$\begingroup\$

Haskell (code.world dialect), 108 86 bytes

drawingOf(c(2)&colored(c(3),white)&0%1&2%3&4%5)
c=solidCircle
a%b=sector(a*60,b*60,10)

Run on code.world!

\$\endgroup\$
8
\$\begingroup\$

C (gcc) (MinGW), 245 244 242 236 223 221 bytes

-6 bytes thanks to ceilingcat.

Added -lm on TiO so that it works there. MinGW does not require it.

Outputs a 3-shade PGM file to STDOUT. Takes width (height is the same) of image as a command line argument.

main(q,v,r,c,m)char**v;{*v=calloc(q+1,q=atoi(v[1]));float R=q/10.1,d;for(r=m=q/2;r--+m;)for(c=m;c--+m;m[*v+(r+m)*q+c]=d<R*5&&d<=R|d>=1.5*R&asin(r/d)+1.5707>(r>0?5:1)*0.5235?:2)d=hypot(c,r);printf("P5 %d %d 2 %s",q,q,*v);}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Perhaps I'm not understanding what I'm looking at, but when I try the 'Try it online!' I just a huge blob of "hollow square" characters. ??? \$\endgroup\$ Commented Nov 24, 2019 at 16:20
  • \$\begingroup\$ @BobJarvis-ReinstateMonica Yeah, it outputs a PGM file using ASCII 1 and 2, which look a bit wonky. Redirect to a file on a local system or copy the TiO output into a file to see the result. \$\endgroup\$
    – gastropner
    Commented Nov 24, 2019 at 18:36
7
\$\begingroup\$

TikZ, 170 bytes

\documentclass[tikz]{standalone}\begin{document}\tikz{\fill circle(10);\foreach\a in{0,120,240}{\fill[white]circle(3)--(\a-60:13)--(\a:13);}\fill circle(2)}\end{document}
\$\endgroup\$
1
  • \$\begingroup\$ it can be reduced to 164 bytes with TikZ \$\endgroup\$
    – Black Mild
    Commented Jan 30, 2020 at 1:25
7
\$\begingroup\$

Logo, 96 bytes

circle 16
rt 90
repeat 3[arc 80 60
arc 24 60
pu
repeat 2[fw 24
pd
fw 56
pu
backward 80
rt 60]pd]

Try it online! Draws just the border.

\$\endgroup\$
1
  • \$\begingroup\$ Sadly the link no longer works but you can paste the code into this online interpreter. \$\endgroup\$
    – Neil
    Commented Mar 23, 2023 at 8:22
7
\$\begingroup\$

Desmos/Cartesian Plane, 103 97 86 84 bytes

(23 arithmetic and comparison operators)

(abs(mod(arctan(x,-y)/\pi*6,4)-2)-1)*max(0,182-abs(x^2+y^2-218))+max(0,16-x^2-y^2)>0

enter image description here

https://www.desmos.com/calculator/hadw7gayfn

enter image description here

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Bah, stupid calculator can't graph it as a polar equation... can you at least save some bytes by using degrees instead of radians? (You can also change the grid to polar, which looks nicer IMHO.) \$\endgroup\$
    – Neil
    Commented Nov 27, 2019 at 1:01
6
\$\begingroup\$

Mathematica (Wolfram Language) 76 71 Bytes

This solution draws the radiation symbol using only the Disk[] primitive, which allows for arcs.

By default a Graphics object in Mathematica has a White background and objects are Black unless otherwise specified. So we first draw three black disk sectors, then a small white disk and finally a smaller inner black disk. Unlike @Mario Carneiro's solution (which is a nice use of RegionPlot), this comes without axes and without the artifacts produced by the inner workings of RegionPlot.

Saved a byte by letting R=2

Graphics@{(d={0,0}~Disk~##&)[10,{#,#+1}Pi/3]&/@{0,2,4},{White,d@3},d@2}

enter image description here

\$\endgroup\$
6
\$\begingroup\$

Mathematica, 93 88 85 76 74 70 bytes

RegionPlot[1.5<#<5&&Sin[3#2]>0||#<1&@@AbsArg[x+I y],{x,-5,5},{y,-5,5}]

-4 bytes thanks to Roman.

It is not clear from the description whether it is required to get rid of the outline and make it black on white, but I think the submission looks best and is shortest like this.

radiation symbol

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 70 bytes: RegionPlot[3/2<#<5&&Sin[3#2]>0||#<1&@@AbsArg[x+I*y],{x,-5,5},{y,-5,5}] \$\endgroup\$
    – Roman
    Commented Nov 27, 2019 at 21:22
5
\$\begingroup\$

PostScript, 183 175 bytes

Code (compressed version):

20 20 scale 9 6 translate<</f{closepath fill}/c{0 360 arc f}/l{10 0 lineto -60 rotate}>>begin 0 0 5 c 1 setgray 3{0 0 moveto l l f} repeat 0 0 1.5 c 0 setgray 0 0 1 c showpage

Code (uncompressed version):

20 20 scale           % over-all scale
9 6 translate         % over-all shift

% define some short-named procedures for later use
<<
  /f { closepath fill }
  /c { 0 360 arc f }  % filled circle (x, y, radius are taken from stack)
  /l { 10 0 lineto
       -60 rotate }   % long line + rotate by 60°
>> begin

0 0 5 c               % big black circle
1 setgray             % set white color
3 {
  0 0 moveto l l f    % white triangle + rotate by 120°
} repeat
0 0 1.5 c             % white circle
0 setgray             % set black color
0 0 1 c               % small black circle
showpage

Result (as animation to see how it is drawn):

result

\$\endgroup\$
5
\$\begingroup\$

Python 3.8, 129 124 122 120 119

def f(N):[print((abs(a:=(i%N+i//N*1j)*2/N-1-1j)<.2)+((a**3).imag<0<.3<abs(a)<1),end=(-i%N==1)*"\n")for i in range(N*N)]

Output (N=20):

00000000000000000000
00000000000000000000
00000100000000010000
00011100000000011100
00011110000000111100
00111111000001111110
01111111000001111111
01111111100011111111
01111111000001111111
01111111011101111111
00000000011100000000
00000000011100000000
00000000000000000000
00000000010100000000
00000000111110000000
00000000111110000000
00000001111111000000
00000011111111100000
00000011111111100000
00000011111111100000

The idea is to represent each point in the plane by a complex number \$x\$. Let the radius of the innermost circle be \$2\$. Then \$x\$ is inside the inner circle if \$|x|<2\$.

The outer parts are a bit more involved. To lie in one of the outer parts, we have to have \$3=1.5\cdot 2< |x| < 5\cdot 2 = 10\$ so that the distance is neither too small nor too large. We also have an angle restriction: the polar angle of \$x\$ has to lie between \$60^\circ\$ and \$120^\circ\$, when taken mod \$120^\circ\$. But if we instead look at \$x^3\$, the angle is multiplied by three, so that the polar angle of \$x^3\$ has to lie between \$180^\circ\$ and \$360^\circ\$ (mod \$360^\circ\$). This is just equivalent to \$\Im(x^3)<0\$.

To put it all together, we have to have \$|x|<2\$ or both of \$3<|x|<10\$ and \$\Im(x^3)<0\$ for \$x\$ to be inside the image. As both conditions are mutually exclusive, their truth values can just be added together.

\$\endgroup\$
2
  • \$\begingroup\$ Try it Online shows this code as 120 bytes tio.run/… \$\endgroup\$ Commented Nov 25, 2019 at 23:07
  • \$\begingroup\$ @Brian Minton You're right - I used len("""...""") in Python to calculate the length, which of course counted the "\n" as one char... Sorry about that \$\endgroup\$
    – ManfP
    Commented Nov 25, 2019 at 23:28
5
\$\begingroup\$

TikZ, 93 bytes

The last comma ; at the end of the code can be missed.

\foreach\i in{0,120,240}\fill[rotate=\i](60:3)arc(60:0:3)--(0:10)arc(0:60:10);\fill circle(2)

TikZ, 164 bytes

\documentclass[tikz]{standalone}\begin{document}\tikz{\foreach\i in{0,120,240}\fill[rotate=\i](60:3)arc(60:0:3)--(0:10)arc(0:60:10);\fill circle(2)}\end{document}

enter image description here

Asymptote 109 bytes

// Run on http://asymptote.ualberta.ca/
for(int i=0;i<3;++i)fill(rotate(i*120)*(arc((0,0),3,60,0)--arc((0,0),10,0,60)--cycle));fill(circle((0,0),2));

Asymptote 117 bytes

// Run on http://asymptote.ualberta.ca/
for(int i: new int[]{0,120,240})fill(rotate(i)*(arc((0,0),3,60,0)--arc((0,0),10,0,60)--cycle));fill(circle((0,0),2));
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I like your approach with arcs and angles. Seems appropiate for this symbol. Here's a plain TeX version that will save you many bytes: \input tikz \tikz{\def~#1{\fill[rotate=60*#1](60:1.5)arc(60:0:1.5)--(0:5)arc(0:60:5);}~0~2~4\fill circle()}\bye. I scaled it by the factor .5 in order to have it displayed on one "page". 111 bytes \$\endgroup\$
    – Joe85AC
    Commented Jun 2, 2020 at 14:33
4
\$\begingroup\$

python 3.8, 220


from PIL import Image as I
from math import*
d=300
h=d//2
r0=d/10
g=range(-h,h)
i=I.frombytes('L',(d,d),bytes([255,0][1.5<(r:=(x*x+y*y)**.5)/r0<5 and(atan2(x,y)/pi+7/6)*1.5%1.>.5 or r<r0]for y in g for x in g))
i.show()

The idea behind is very simple: we count (x,y) from the center of image and r=(x*x+y*y)**.5 is the distance between point and the center.
The point is black if either r<r0 where r0 is 1/5 distance from center to a side
or if 5*r0<r<1.5*r0 (see the diagram in the question) and the angle from center to the point (computed with math.atan2) is in selected ranges. 1.5 and 7/6 there were obtained almost empirically, but could be reasoned too.
The other (most) part is a wrap-in.

\$\endgroup\$
6
  • \$\begingroup\$ I don't fully understand this code, but is there any reason for h=d//2 instead of h=150? Or r0=d/10 instead of say k=30.? \$\endgroup\$
    – 79037662
    Commented Nov 23, 2019 at 22:55
  • 1
    \$\begingroup\$ No reason except If you use raster images, you should take a parameter (or two) as input that lets you adjust the resolution of the output (e.g. width/height). so it should be d=int(input()) \$\endgroup\$ Commented Nov 24, 2019 at 4:45
  • \$\begingroup\$ Is there a point to the leading newline? Or to assigning to i instead of calling.show() on the result? \$\endgroup\$
    – Jo King
    Commented Nov 24, 2019 at 5:57
  • \$\begingroup\$ You seem to be aware that the resolution should be inputted, but your code has it hardcoded instead. Also, r0 can just be a different single letter variable \$\endgroup\$
    – Jo King
    Commented Nov 24, 2019 at 6:06
  • \$\begingroup\$ OK you can count +9 bytes for input and -3 bytes for r0, but I especially like score of 220 in the context of danger, it's the power voltage (220V) in xUSSR usual consumer voltage) \$\endgroup\$ Commented Nov 24, 2019 at 12:41
4
\$\begingroup\$

Red, 237 218 bytes

Red[needs: 'View]
g: func[n][a: compose[arc(s: n / 2.0 * 50x50)(s)60 60 closed
rotate 120(s)]view compose/deep[base(s * 2)draw[(f: 'fill-pen)black(a)(a)(a)
pen gray line-width(0.1 * s/1)(f)black circle(s)(s/1 / 4.0)]]]

enter image description here

Takes a parameter n - the width/height in multiples of 50.

\$\endgroup\$
4
\$\begingroup\$

Desmos, 3+70 64=73 67 bytes

After seeing Will Chen's answer and seeing that the online link no longer seemed to work, I figured I'd start at it from scratch, and ended up with 11 fewer bytes.

r<2
max(0,mod(-sign(x)arctan(y/x),120)-60)(x^2+y^2-9)(x^2+y^2-100)<0

View it online

Edit: realized max is unnecessary for the latter two functions. It's required for the first function to zero out a lot of areas, but this might be able to be improved. This makes this the shortest answer in a non-golfing language, beating out Mathematica, with some potential for improvement.

This originally used a bunch of piecewise conditionals, which simply evaluate to 1 if true and undefined if false, making them handy for this purpose. However, by just multiplying them through and comparing to 0, we can check for polarity in a shorter way. The reason we do <0 at the end instead of >0 like you may expect is that the last block, checking if r>10, needs to evaluate to false (negative). The only other notable thing is the polarity check in the first part because arctan(y/x) doesn't necessarily work as well for angle-finding as you might hope.

\$\endgroup\$
3
\$\begingroup\$

Ruby, 91 100 bytes

->s{(w=-(s/=2)..s).map{|x|w.map{|r|a=x*x+r*=r;' O'[a<(b=s*s)/25||a>b/11&&a<b&&x*(r*4-a)<0?1:0]}*''}}

Try it online!

Accepting 1 parameter (size of the image).

Example output for s=40:

          O                   O          
         OO                   OO         
       OOOOO                 OOOOO       
      OOOOOO                 OOOOOO      
     OOOOOOOO               OOOOOOOO     
     OOOOOOOOO             OOOOOOOOO     
    OOOOOOOOOO             OOOOOOOOOO    
   OOOOOOOOOOOO           OOOOOOOOOOOO   
   OOOOOOOOOOOO           OOOOOOOOOOOO   
  OOOOOOOOOOOOOO         OOOOOOOOOOOOOO  
  OOOOOOOOOOOOOO         OOOOOOOOOOOOOO  
 OOOOOOOOOOOOOOOO       OOOOOOOOOOOOOOOO 
 OOOOOOOOOOOOOOOO       OOOOOOOOOOOOOOOO 
 OOOOOOOOOOOOOOO         OOOOOOOOOOOOOOO 
 OOOOOOOOOOOOOO   OOOOO   OOOOOOOOOOOOOO 
 OOOOOOOOOOOOOO  OOOOOOO  OOOOOOOOOOOOOO 
 OOOOOOOOOOOOOO  OOOOOOO  OOOOOOOOOOOOOO 
                 OOOOOOO                 
                 OOOOOOO                 
                 OOOOOOO                 
                  OOOOO                  


                 OOO OOO                 
                OOOOOOOOO                
                OOOOOOOOO                
               OOOOOOOOOOO               
               OOOOOOOOOOO               
              OOOOOOOOOOOOO              
              OOOOOOOOOOOOO              
             OOOOOOOOOOOOOOO             
            OOOOOOOOOOOOOOOOO            
            OOOOOOOOOOOOOOOOO            
           OOOOOOOOOOOOOOOOOOO           
           OOOOOOOOOOOOOOOOOOO           
            OOOOOOOOOOOOOOOOO            
              OOOOOOOOOOOOO
\$\endgroup\$
1
  • \$\begingroup\$ how............. \$\endgroup\$
    – Razetime
    Commented Sep 6, 2020 at 12:19
3
\$\begingroup\$

OpenSCAD, 153 bytes

module a(){polygon([[0,0],[5,0],[5,10]]);}module b(){a();rotate(120)a();rotate(240)a();}circle();intersection(){difference(){circle(5);circle(1.5);}b();}

A low-poly radiation symbol

Uncompressed:

module triangle()
{
    polygon(points=[[0,0],[5,0],[5,10]]);
}

module triangles() {
    triangle();
    rotate(120) triangle();
    rotate(240) triangle();
}

module radiation()
{
    circle($fn = 100);
    intersection() {
        difference() {
            circle(5, $fn = 100);
            circle(1.5, $fn = 100);
        }
        triangles();
    }
}

radiation();

A high-poly radiation symbol

Notice the extra $fn = 100 in the circles, which are used to make them higher-resolution polygon. We could add $fs=.1; at the beginning of the file, which would also improve the resolution.

\$\endgroup\$
3
\$\begingroup\$

SVG(HTML5), 114 bytes

<svg viewBox=-1,-1,2,2><circle r=.65 fill=none stroke=#000 stroke-width=.7 stroke-dasharray=0,.68,0 /><circle r=.2

An alternative solution to the other SVG answers. Uses the stroke dash property to create the 'wings'.

The value of the .68 should be equal to 0.65 / 3 * PI, or 0.680678408... to be more accurate.

If incorrect rotation is allowed, this can be reduced to 110 bytes:

<svg viewBox=-1,-1,2,2><circle r=.65 fill=none stroke=#000 stroke-width=.7 stroke-dasharray=.68 /><circle r=.2

\$\endgroup\$
2
\$\begingroup\$

GLSL / Shadertoy, 181 bytes

void mainImage(out vec4 o,vec2 c)
{
    vec2 p=(c-iResolution.xy/2.)/iResolution.y;
    float k=length(p),h=acos(-1.)/3.;
    o=step(0.,min(k-.1,max(k-.5,.15-k)*step(mod(atan(p.y,p.x),h+h),h)))-o;
}

Copy and paste this code into the editor then press the play button to run the shader.

The shader uses the signed distance of the shapes to be able to use the union and intersection operations to generate the symbol.

\$\endgroup\$
1
  • \$\begingroup\$ 154 bytes void mainImage(out vec4 o,vec2 c){c=(c-vec2(4e2,225.))/450.;float k=length(c),h=1.047;o+=sign(k-.1)-sign((k-.15)*(k-.5))*-step(mod(atan(c.y,c.x),h+h),h);} \$\endgroup\$ Commented Jul 9, 2021 at 19:04
2
\$\begingroup\$

TI-BASIC (TI-84+), 1042 bytes

"000000000000000000000000000000000000000000000000000000000000000300000000000000780000006000001FC000000F800003FC000001FC00007FE000001FE0000FFE000003FF0001FFF000003FF8003FFF000007FFC003FFF80000FFFC007FFFC0000FFFE00FFFFC0001FFFF00FFFFE0001FFFF01FFFFE0003FFFF81FFFFF0007FFFF83FFFFF8007FFFFC3FFFFF800FFFFFC3FFFFFC00FFFFFC7FFFFFC01FFFFFE7FFFFFC01FFFFFE7FFFFF801FFFFFE7FFFFF0F0FFFFFEFFFFFE3FC7FFFFFFFFFFE7FE7FFFFFFFFFFC7FE3FFFFFFFFFFCFFF3FFFFFFFFFFCFFF3FFFFF000000FFF3FFFFF000000FFF0000000000007FE0000000000007FE0000000000003FC0000000000000F0000000000000000000000000000604000000000000FFE000000000001FFE000000000001FFF000000000003FFF800000000007FFF800000000007FFFC0000000000FFFFC0000000000FFFFE0000000001FFFFF0000000003FFFFF0000000003FFFFF8000000007FFFFF8000000007FFFFFC00000000FFFFFFC00000001FFFFFFE00000001FFFFFFF00000003FFFFFFF00000001FFFFFFF80000000FFFFFFF000000003FFFFFC0000000007FFFE000000000007FE000000→Str1
AxesOff
15→N
4→dim(∟A
For(I,1,60N
sub(Str1,I,1
inString("0123456789ABCDEF",Ans)-1→D
For(B,4,1,-1
D≥2(B-1→∟A(B
If ∟A(B
D-2^(B-1→D
End
For(E,1,4
If ∟A(5-E
Pxl-On(iPart(I/N),E+4remainder(I,N
End
End

Oh man, this one was rough. The TI series of calculators do have shading functionality between functions, but that just don't cut it.
Furthermore, I was limited to 60x60 pixels, since drawing on the 62nd row or lower would result in ERR: ARGUMENT error being thrown and 60 fits the radii ratios mentioned in the challenge perfectly: $$ R = 12 \\ 1.5R = 18 \\ 5R = 60$$

So, I opted to convert a string of hexadecimal characters to pixels.

The pixels drawn to the screen will look like this:

Ionized Radiation Hazard symbol

The very long string you see on the first line of the program looks like this when formatted:

000000000000000
000000000000000
000000000000000
000000000000000
000300000000000
000780000006000
001FC000000F800
003FC000001FC00
007FE000001FE00
00FFE000003FF00
01FFF000003FF80
03FFF000007FFC0
03FFF80000FFFC0
07FFFC0000FFFE0
0FFFFC0001FFFF0
0FFFFE0001FFFF0
1FFFFE0003FFFF8
1FFFFF0007FFFF8
3FFFFF8007FFFFC
3FFFFF800FFFFFC
3FFFFFC00FFFFFC
7FFFFFC01FFFFFE
7FFFFFC01FFFFFE
7FFFFF801FFFFFE
7FFFFF0F0FFFFFE
FFFFFE3FC7FFFFF
FFFFFE7FE7FFFFF
FFFFFC7FE3FFFFF
FFFFFCFFF3FFFFF
FFFFFCFFF3FFFFF
000000FFF3FFFFF
000000FFF000000
0000007FE000000
0000007FE000000
0000003FC000000
0000000F0000000
000000000000000
000000604000000
000000FFE000000
000001FFE000000
000001FFF000000
000003FFF800000
000007FFF800000
000007FFFC00000
00000FFFFC00000
00000FFFFE00000
00001FFFFF00000
00003FFFFF00000
00003FFFFF80000
00007FFFFF80000
00007FFFFFC0000
0000FFFFFFC0000
0001FFFFFFE0000
0001FFFFFFF0000
0003FFFFFFF0000
0001FFFFFFF8000
0000FFFFFFF0000
00003FFFFFC0000
000007FFFE00000
0000007FE000000

Each hexadecimal digit encodes to a series of 4 pixels drawn to the screen. For each bit set in the digit, a pixel will be drawn.

Explanation:

"000 ... 000→Str1                       ;set the digit string to convert
AxesOff                                 ;get rid of the axes on the graph since
                                        ;  it'll be in the way
15→N                                    ;set N to 15 in order to save a few bytes
4→dim(∟A                                ;set the length of the list A to 4 elements
For(I,1,60N                             ;loop 900 times.  There are 60 lines to draw
                                        ;  and 15 digits per line to convert
sub(Str1,I,1                            ;get the current hexadecimal digit
inString("0123456789ABCDEF",Ans)-1→D    ;convert it to base 10, store the result in D
For(B,4,1,-1                            ;convert number to its binary representation
D≥2(B-1→∟A(B
If ∟A(B
D-2^(B-1→D
End
For(E,1,4                               ;loop over each bit in said representation
If ∟A(5-E                               ;and only draw the pixel if this bit is set
                                        ; (bit order is reversed)
Pxl-On(iPart(I/N),E+4remainder(I,N      ;pixel row (Y) is I/N, pixel column (X) is
                                        ; 4*(I%N)+E
End
End

Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

\$\endgroup\$
2
\$\begingroup\$

T-SQL, 185 bytes

DECLARE @ GEOMETRY='POINT(6 6)',@b GEOMETRY='POLYGON((12 6,9 0,3 12,9 12,3 0,0 6,12 6))'SELECT @.STBuffer(5).STDifference(@b.MakeValid().STUnion(@.STBuffer(1.5))).STUnion(@.STBuffer(1))

I shifted the center from (0,0) to (6,6) to reduce the number of negative numbers needed; this saves a byte or two.

This code isn't quite long enough to benefit from the REPLACE() trick that was needed for the Biohazard symbol.

This was done using SQL geo-spatial features introduced in SQL 2008.

Visual of output, with annotated code:

enter image description here

For more T-SQL drawing, see my Biohazard symbol and my Easter Bunny.

\$\endgroup\$
2
\$\begingroup\$

Desmos, 60 bytes

w=hsv(0,0,1)
r<5\{[0,3,6]40<\theta<[1,3,5]60\}
xx+yy<9/4
r<1

Try it on Desmos

This is the version without scaling, now the shortest Desmos answer.

Desmos, 178 161 153 126 119 72 68 67 bytes

R=1
w=hsv(0,0,1)
r<5R\{[0,3,6]40<\theta<[1,3,5]60\}
xx+yy<9RR/4
r<R

Try it on Desmos

-12 bytes thanks to @Steffan

-27 bytes by switching to degrees and extracting the "arms" to a function

-55 bytes and fix thanks to @Aiden Chow

-1 byte thanks to emanresu A

By far the longest Desmos answer yet, this is now the second shortest answer. Oh, and mine is scalable, just move the \$R\$ slider.

\$\endgroup\$
6
  • \$\begingroup\$ u dont need the parens around (2π) and (4π)` and (5π) \$\endgroup\$
    – naffetS
    Commented May 5, 2022 at 18:23
  • \$\begingroup\$ le can be <= even if it doesn't render right \$\endgroup\$
    – naffetS
    Commented May 5, 2022 at 18:23
  • \$\begingroup\$ 2.25 can be 9/4 \$\endgroup\$
    – emanresu A
    Commented May 5, 2022 at 19:54
  • \$\begingroup\$ also u dont need \left and \right with the newline if u paste it in right \$\endgroup\$
    – naffetS
    Commented May 5, 2022 at 23:28
  • \$\begingroup\$ u missed one thing, xx+yy<RR can be r<RR \$\endgroup\$
    – naffetS
    Commented May 6, 2022 at 15:46
1
\$\begingroup\$

Processing, 172 bytes

noStroke();background(255);fill(0);for(float i=-60;i<=300;i+=120)arc(50,50,100,100,radians(i),radians(i+60),PIE);fill(255);circle(50,50,30);fill(0);circle(50,50,20);

Un-minified code:

noStroke();
background(255);
fill(0);
for(float i=-60;i<=300;i+=120)arc(50,50,100,100,radians(i),radians(i+60),PIE);
fill(255);
circle(50,50,30);
fill(0);
circle(50,50,20);

Output

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.