\input vec2d-parse
\input vec2d-def
\input vec2d-fp
\input vec2d-c
\input vec2d-triangle
\input vec2d-d
\input vec2d-l
\input vec2d-dl
\input vec2d-cdl
\newcount\VDDlangleequalcount
\VDDlangleequalcount0
\newcount\VDDdlinepartequalcount
\VDDdlinepartequalcount0
\newcount\VDDdlineparcount
\VDDdlineparcount0
\catcode`@=11%
\def\VDDdef@defined{}%
%
\let\then\iftrue % trick to get nested self-defined conditionals to work
\newif\ifVDD@test
%
\def\ifVDDucase#1\then{%
  \ifx#1A\VDD@testtrue\else\ifx#1B\VDD@testtrue\else\ifx#1C\VDD@testtrue\else
  \ifx#1D\VDD@testtrue\else\ifx#1E\VDD@testtrue\else\ifx#1F\VDD@testtrue\else
  \ifx#1G\VDD@testtrue\else\ifx#1H\VDD@testtrue\else\ifx#1I\VDD@testtrue\else
  \ifx#1J\VDD@testtrue\else\ifx#1K\VDD@testtrue\else\ifx#1L\VDD@testtrue\else
  \ifx#1M\VDD@testtrue\else\ifx#1N\VDD@testtrue\else\ifx#1O\VDD@testtrue\else
  \ifx#1P\VDD@testtrue\else\ifx#1Q\VDD@testtrue\else\ifx#1R\VDD@testtrue\else
  \ifx#1S\VDD@testtrue\else\ifx#1T\VDD@testtrue\else\ifx#1U\VDD@testtrue\else
  \ifx#1V\VDD@testtrue\else\ifx#1W\VDD@testtrue\else\ifx#1X\VDD@testtrue\else
  \ifx#1Y\VDD@testtrue\else\ifx#1Z\VDD@testtrue\else\VDD@testfalse
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
  \ifVDD@test
}%
%
\def\VDDstart{\bgroup}%
\def\VDDend{\egroup}%
\def\VDDx#1{\csname VDD@#1x\endcsname}%
\def\VDDy#1{\csname VDD@#1y\endcsname}%
%
\def\VDDcopy@@#1&#2:#3&#4:#5{%
  %\message{got 1=#1< 2=#2< 3=#3< 4=#4< 5=#5<}%
  #5\expandafter\let\csname VDD@#1x\expandafter\endcsname
      \csname VDD@#3x\endcsname
  #5\expandafter\let\csname VDD@#1y\expandafter\endcsname
      \csname VDD@#3y\endcsname
  \ifx\end#2\end\else\VDDcopy@@#2:#4:#5\fi
}%
\def\VDDgcopy@#1:#2 {\VDDcopy@@#1:#2:{\global}}%
\def\VDDcopy@#1:#2 {\VDDcopy@@#1:#2:{\relax}}%
\def\VDDzero@#1&#2 {%
  \expandafter\expandafter\expandafter
  \def\VDDx{#1}{0}%
  \expandafter\expandafter\expandafter
  \def\VDDy{#1}{0}%
  \ifx\end#2\end\else\VDDzero@#2 \fi
}%
\def\VDDonecircular#1#2&#3:#4 {%
  \ifx\end#3\end\errmessage{not enough points given}\fi
  #1#2&#3#2&:#4
}%
\def\VDDtwocircular#1#2&#3&#4:#5 {%
  \ifx\end#4\end\errmessage{not enough points given}\fi
  #1#2&#3&#4#2&#3&:#5
}%
\def\VDDprint@#1&#2 {%
  $#1(\VDDx{#1},\VDDy{#1})$
  \ifx\end#2\end\else\VDDprint@#2 \fi
}%
\def\VDDprint#1 {%
  \VDDparse@\VDDdef@\VDDparsetmp@#1
  \expandafter\VDDprint@\VDDparsetmp@&
}%
\def\VDDmessage@#1&#2 {%
  \message{#1(\VDDx{#1},\VDDy{#1})}%
  \ifx\end#2\end\else\VDDmessage@#2 \fi
}%
\def\VDDmessage#1 {%
  \VDDparse@\VDDdef@\VDDparsetmp@#1
  \expandafter\VDDmessage@\VDDparsetmp@&
}%
%
\def\VDDround@#1&#2 {%
 \expandafter\expandafter\expandafter
 \FPround\VDDx{#1}{\VDDx{#1}}{\VDDd@psdecs}% 
 \expandafter\expandafter\expandafter
 \FPround\VDDy{#1}{\VDDy{#1}}{\VDDd@psdecs}% 
 \ifx\end#2\end\else\VDDround@#2 \fi
}%
%
% danger, our calculations are not exact...
\def\ifVDDeq#1#2\then{%
  \ifFPeq{\VDDx{#1}}{\VDDx{#2}}\then
    \ifFPeq{\VDDy{#1}}{\VDDy{#2}}\then
      \VDD@testtrue
    \else
      \VDD@testfalse
    \fi
  \else
    \VDD@testfalse
  \fi
  \ifVDD@test
}%
\def\ifVDDzero#1\then{%
  \VDD@testfalse
  \ifFPzero{\VDDx{#1}}\then
    \ifFPzero{\VDDy{#1}}\then
      \VDD@testtrue
    \fi
  \fi
  \ifVDD@test
}%
\def\ifVDDpossharp#1\then{%
  \VDD@testtrue
  \ifFPneg{#1}\then\VDD@testfalse\fi
  \ifFPgt{#1}{90}\then\VDD@testfalse\fi
  \ifVDD@test
}%
%
% Angles must be stored in degrees: -180 < \angle <= 180
%
% angle operations
\def\VDDnormangle@@#1{%
  \FPifgt{#1}{180}\FPsub{#1}{#1}{360}\fi
  \FPifgt{#1}{-180}\else\FPadd{#1}{#1}{360}\fi
}%
\def\VDDsubangle@@#1#2#3{%
  \FPsub{#1}{#2}{#3}%
  \VDDnormangle@@{#1}%
}%
\def\VDDaddangle@@#1#2#3{%
  \FPadd{#1}{#2}{#3}%
  \VDDnormangle@@{#1}%
}%
%
\catcode`@=12%
