%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% pst-poly.tex --- Generation of polygons with PSTricks
%%
%% Author          : Denis GIROU (CNRS/IDRIS - France) <Denis.Girou@idris.fr>
%% Created the     : Mon Jan 16 19:01:42 1995
%% Last mod. by    : Denis GIROU (CNRS/IDRIS - France) <Denis.Girou@idris.fr>
%% Last mod. the   : Thu Jul  9 22:48:58 1998
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\fileversion{1.4}
\def\filedate{98/07/09}

%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt.

\message{`PST-Polygon' v\fileversion, \filedate\space (Denis Girou)}

\csname PSTPolygonLoaded\endcsname
\let\PSTPolygonLoaded\endinput

% Require PSTricks, pst-node and multido packages
\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi
\ifx\PSTnodesLoaded\endinput\else\input pst-node.tex\fi
\ifx\MultidoLoaded\endinput\else\input multido.tex\fi

% DPC interface to the `keyval' package (until keyval based version of PSTricks)
\input pst-key.tex

\edef\PstAtCode{\the\catcode`\@}
\catcode`\@=11\relax

% Definition of the parameters
% ----------------------------

% "pspicture" environment or not?
\newif\ifPst@PstPicture
\define@key{psset}{PstPicture}[true]{%
\@nameuse{Pst@PstPicture#1}}

% Rotation of the polygon (on 360 degrees)
\define@key{psset}{PolyRotation}{%
\edef\psk@PolyRotation{#1}}

% Number of sides of the polygon
\define@key{psset}{PolyNbSides}{%
\pst@cntg=#1\relax
\edef\psk@PolyNbSides{\the\pst@cntg}}

% Offset to obtain next node
\define@key{psset}{PolyOffset}{%
\pst@cntg=#1\relax
\edef\psk@PolyOffset{\the\pst@cntg}}

% Position of the intermediate point
\newdimen\psl@PolyIntermediatePoint
\define@key{psset}{PolyIntermediatePoint}{%
\edef\psk@PolyIntermediatePoint{#1}}

% Name of the polygon
\define@key{psset}{PolyName}{%
\edef\ps@PolyName{#1}}

% Nodes joined by lines or curves?
\newif\ifPst@PolyCurves
\define@key{psset}{PolyCurves}[true]{%
\@nameuse{Pst@PolyCurves#1}}

% Polygon or epicycloid?
\newif\ifPst@PolyEpicycloid
\define@key{psset}{PolyEpicycloid}[true]{%
\@nameuse{Pst@PolyEpicycloid#1}}

% Default values
% --------------
% 0 degree rotation, 5 sides, no offset, no intermediate point
% (9999 i.e. not used), no name, points joined by lines, no epicycloid
\setkeys{psset}{%
PstPicture=true,PolyRotation=0,PolyNbSides=5,PolyOffset=1,
PolyIntermediatePoint=,PolyName=,PolyCurves=false,PolyEpicycloid=false}

% The macro \PstPolygon for generic polygons
% ------------------------------------------

\def\PstPolygon{%
\pst@ifstar{\@ifnextchar[\@PstPolygon{\@PstPolygon[]}}}
\def\@PstPolygon[#1]{{%
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
%
% Validation of the parameters
\ifnum\psk@PolyNbSides<3
{\@pstrickserr{PolyNbSides must be greater than
   2 (and not `\psk@PolyNbSides')}\@eha}%
\fi
\ifnum\psk@PolyNbSides>200
{\@pstrickserr{PolyNbSides must be less than
   201 (and not `\psk@PolyNbSides')}\@eha}%
\fi
\ifnum\psk@PolyOffset<1
{\@pstrickserr{PolyOffset must be greater than
   0 (and not `\psk@PolyOffset')}\@eha}%
\fi
%
% Now the "real" code
\ifodd\psk@PolyOffset
  \def\Pst@PolyDecimal{.5}%
\else
  \def\Pst@PolyDecimal{}%
\fi
%
\SpecialCoor                    % To be able to use polar coordinates
\ifPst@PstPicture\pspicture(-1,-1)(1,1)\fi % "pspicture" environment
\rput{\psk@PolyRotation}(0,0){%   Rotation if needed
  \degrees[\psk@PolyNbSides]
  % We must recompute it here if unit has change after affectation
  % (for instance \psset{PolyIntermediatePoint=0.38}\PstPolygon{unit=2})
  \pssetlength{\psl@PolyIntermediatePoint}{\psk@PolyIntermediatePoint}
  % If we have to define names for nodes
  \ifx\ps@PolyName\@empty
  \else
    \pnode(0,0){\ps@PolyName 0}   % Center of the polygon
    \ifnum\psxunit=\psyunit
      \def\Pst@PolyNode{\pnode(1;\i)}%
    \else
      \def\Pst@PolyNode{%
        \pnode(!\i\space 360 \psk@PolyNbSides\space div mul cos %
                \i\space 360 \psk@PolyNbSides\space div mul sin)}%
    \fi
    \multido{\i=0+1}{\psk@PolyNbSides}{%
      \Pst@PolyNode{\ps@PolyName\the\multidocount}}
  \fi
  %
  \pscustom{%
    \ifPst@PolyEpicycloid       % Code for epicycloids
      \pst@cnta=\psk@PolyNbSides
      \divide\pst@cnta\tw@
      % We just draw lines between each point and it opposite, with possible gap
      \multido{\i=0+1}{\psk@PolyNbSides}{%
        \moveto(1;\i)
        \lineto(1;\the\pst@cnta)
        \advance\pst@cnta\psk@PolyOffset}
    \else                       % Code for polygons
      % Starting point
      \ifnum\psxunit=\psyunit
        \moveto(1,0)
      \else
        \moveto(! 1 0)
      \fi
      \ifx\psk@PolyIntermediatePoint\@empty % No intermediate points
        \ifnum\psxunit=\psyunit
          \def\Pst@PolyJunction{\lineto(1;\i)}%
        \else
          \def\Pst@PolyJunction{\lineto%
            (!\i\space 360 \psk@PolyNbSides\space div mul cos %
              \i\space 360 \psk@PolyNbSides\space div mul sin)}%
        \fi
        \multido{\i=\psk@PolyOffset+\psk@PolyOffset}{\psk@PolyNbSides}{%
          \Pst@PolyJunction}    % End \multido
      \else                     % Intermediate points
        \ifPst@PolyCurves       % Type of junction
          \let\Pst@PolyJunctionType\pscurve
        \else
          \let\Pst@PolyJunctionType\psline
        \fi
        \ifnum\psxunit=\psyunit
          \def\Pst@PolyJunction{\Pst@PolyJunctionType%
            (\psl@PolyIntermediatePoint;\the\pst@cnta\Pst@PolyDecimal)(1;\i)}%
        \else
          \def\Pst@PolyJunction{\Pst@PolyJunctionType%
            (!\psk@PolyIntermediatePoint\space %
                \the\pst@cnta\Pst@PolyDecimal\space 360 %
                  \psk@PolyNbSides\space div mul cos mul %
              \psk@PolyIntermediatePoint\space %
                \the\pst@cnta\Pst@PolyDecimal\space 360 %
                  \psk@PolyNbSides\space div mul sin mul)
            (!\i\space 360 \psk@PolyNbSides\space div mul cos %
              \i\space 360 \psk@PolyNbSides\space div mul sin)}%
        \fi
        \pst@cnta=\psk@PolyOffset
        \divide\pst@cnta\tw@
        \multido{\i=\psk@PolyOffset+\psk@PolyOffset}{\psk@PolyNbSides}{%
          \Pst@PolyJunction
          \advance\pst@cnta\psk@PolyOffset} % End \multido
      \fi                       % End \ifx\psk@PolyIntermediatePoint
    \fi}                        % End \ifPst@PolyEpicycloid and \pscustom
    \ifx\PstPolygonNode\@undefined
    \else
      \multido{\INode=0+\psk@PolyOffset}{\psk@PolyNbSides}{%
        \PstPolygonNode}        % Command to execute at each node
    \fi}                        % End \rput
\ifPst@PstPicture\endpspicture\fi}} % End of "pspicture" environment

% Pre-defined polygons
% --------------------

% Triangle (three sides)
\def\PstTriangle{%
\pst@ifstar{\@ifnextchar[\@PstTriangle{\@PstTriangle[]}}}
\def\@PstTriangle[#1]{{%
\setkeys{psset}{PolyNbSides=3,PolyRotation=90}% For triangle (360/3*(3/4))
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Square (four sides)
\def\PstSquare{%
\pst@ifstar{\@ifnextchar[\@PstSquare{\@PstSquare[]}}}
\def\@PstSquare[#1]{{%
\setkeys{psset}{PolyNbSides=4,PolyRotation=45}% For square (360/4/2)
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Pentagon (five sides)
\def\PstPentagon{%
\pst@ifstar{\@ifnextchar[\@PstPentagon{\@PstPentagon[]}}}
\def\@PstPentagon[#1]{{%
\setkeys{psset}{PolyNbSides=5,PolyRotation=18}% For pentagon (360/5/4)
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Hexagon (six sides)
\def\PstHexagon{%
\pst@ifstar{\@ifnextchar[\@PstHexagon{\@PstHexagon[]}}}
\def\@PstHexagon[#1]{{%
\setkeys{psset}{PolyNbSides=6}%   For hexagon
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Heptagon (seven sides)
\def\PstHeptagon{%
\pst@ifstar{\@ifnextchar[\@PstHeptagon{\@PstHeptagon[]}}}
\def\@PstHeptagon[#1]{{%
\setkeys{psset}{PolyNbSides=7,PolyRotation=38.57}% For heptagon (360/7*(3/4))
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Octogon (height sides)
\def\PstOctogon{%
\pst@ifstar{\@ifnextchar[\@PstOctogon{\@PstOctogon[]}}}
\def\@PstOctogon[#1]{{%
\setkeys{psset}{PolyNbSides=8,PolyRotation=22.5}% For octogon (360/8/2)
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Nonagon (nine sides)
\def\PstNonagon{%
\pst@ifstar{\@ifnextchar[\@PstNonagon{\@PstNonagon[]}}}
\def\@PstNonagon[#1]{{%
\setkeys{psset}{PolyNbSides=9,PolyRotation=10}% For nonagon (360/9/4)
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Decagon (ten sides)
\def\PstDecagon{%
\pst@ifstar{\@ifnextchar[\@PstDecagon{\@PstDecagon[]}}}
\def\@PstDecagon[#1]{{%
\setkeys{psset}{PolyNbSides=10}%  For decagon
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Dodecagon (twelve sides)
\def\PstDodecagon{%
\pst@ifstar{\@ifnextchar[\@PstDodecagon{\@PstDodecagon[]}}}
\def\@PstDodecagon[#1]{{%
\setkeys{psset}{PolyNbSides=12,PolyRotation=15}% For dodecagon (360/12/2)
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Star with five leaves, with internal lines
\def\PstStarFiveLines{%
\pst@ifstar{\@ifnextchar[\@PstStarFiveLines{\@PstStarFiveLines[]}}}
\def\@PstStarFiveLines[#1]{{%
\setkeys{psset}{PolyOffset=2,PolyRotation=18}% For star with internal lines
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

% Star with five leaves
\def\PstStarFive{%
\pst@ifstar{\@ifnextchar[\@PstStarFive{\@PstStarFive[]}}}
\def\@PstStarFive[#1]{{%
\setkeys{psset}{PolyIntermediatePoint=0.38,PolyRotation=18}%  For star
\setkeys{psset}{#1}%            % Affectation of local parameters
\if@star\solid@star\fi          % Stared version
\PstPolygon}}

\catcode`\@=\PstAtCode\relax
\endinput
%%
%% END: pst-poly.tex
