Biohazard symbol in PostScript

%! biohazard.ps: draw a biohazard warning symbol
%% 
%% Version 1.01, copyright 1994 by Jed Hartman.
%% Last modification (to notes/docs only): 5 July 2023.
%%
%% Permission to use, copy, modify, and distribute this software
%% and its (ha!) documentation, in whole or in part, for any
%% purpose and without fee is hereby granted, provided that: (a)
%% the above copyright notice appear in all copies; (b) both the
%% copyright notice and this permission notice appear in
%% supporting documentation; and (c) no fee is charged for further
%% redistribution of the software. This software is provided "as
%% is" without express or implied warranty.
%% 
%% Thanks to Scott Byer for help with the ring-drawing routine,
%% and Jef Poskanzer for the permission-to-use notice. I'm fairly
%% new to PostScript programming; comments on style and algorithm
%% from experienced PS programmers would be more than welcome.
%% Address all comments to logos@kith.org. Note that the
%% proportions of this version were approximated by
%% reverse-engineering an Adobe Illustrator version Jef sent me
%% which had the standard proportions; if anyone could tell me
%% what the relative sizes and positions of the components are
%% really supposed to be, I'd be grateful. At any rate, this
%% version does scale easily; just change outcent, and everything
%% else should scale accordingly.
%% 
%% Note that this version is only in black and white, and relies
%% on the page background being white (there are several instances
%% of drawing white over black).


/in  { 72 mul } def                        % 1 inch

/outcent { 100 } def                       % center of black circles
/incent { outcent 11 mul 8 div } def       % center of white circles
/inrad { outcent 9 mul 10 div } def        % radius of white circles
/outrad { outcent 5 mul 4 div } def        % radius of black circles

/ringrad { outcent 9 mul 10 div } def      % radius of ring
/ringwidth { outcent 8 div } def           % half of width of ring
/ringcutwidth { outcent 25 div } def       % width of cuts in ring
/centcutwidth { outcent 10 div } def       % width of cuts in center area
/centrad { outcent 3 mul 8 div } def       % radius of central white circle

/center { 4.25 in 5.5 in translate } def   % command to center symbol
/circle { 0 360 arc } def                  % draw a ccw circle
/circlen { 360 0 arcn } def                % draw a cw circle


gsave

center    % Center the design on an 8.5" x 11" letter-sized page.


%%
%% Draw the main shape.  This could be done by tracing the
%% boundary of the shape, but it's simpler (and easier to
%% generalize) to draw more than necessary and then paint over
%% part of it in white.
%%

% Start with three overlapping black circles:
0 setgray
3 {
    0 outcent outrad circle fill
    -120 rotate
} repeat

% Then cover part of each black circle with a white circle:
1 setgray
3 {
    0 incent inrad circle fill
    -120 rotate
  } repeat
0 setgray


%%
%% Draw a ring all the way around the center.
%%

newpath
ringrad ringwidth add 0 moveto 0 0 ringrad ringwidth add circle closepath
ringrad ringwidth sub 0 moveto 0 0 ringrad ringwidth sub circlen closepath
fill


%%
%% Now cut the ring with white arcs and the center with white segments.
%% 

1 setgray

gsave

ringcutwidth setlinewidth
3 {
    % Draw a 180-degree white curve (which is longer than strictly necessary):
    0 incent inrad ringcutwidth 2 div sub 0 180 arcn stroke
    -120 rotate
  } repeat

centcutwidth setlinewidth
3 {
    % Make the little cuts in the center part:
    0 0 moveto
    0 incent 2 div lineto stroke
    -120 rotate
  } repeat

grestore


%%
%% Finally, put a small white circle in the very center.
%%

0 0 centrad circle fill

0 setgray


%%
%% All done.
%%

grestore    % Are nested gsave/grestores okay?  Seems to work...

showpage