diff options
Diffstat (limited to 'macros/latex/contrib/wargame/source/hex/board.dtx')
-rw-r--r-- | macros/latex/contrib/wargame/source/hex/board.dtx | 393 |
1 files changed, 246 insertions, 147 deletions
diff --git a/macros/latex/contrib/wargame/source/hex/board.dtx b/macros/latex/contrib/wargame/source/hex/board.dtx index fd0af295fb..7c791a72b3 100644 --- a/macros/latex/contrib/wargame/source/hex/board.dtx +++ b/macros/latex/contrib/wargame/source/hex/board.dtx @@ -18,82 +18,261 @@ % % % \begin{macrocode} -\tikzset{ - hex/board frame/.style={draw} -} \def\boardframe{% - \@ifnextchar[{\bo@rdframe}{\bo@rdframe[0]}%} + \@ifnextchar[{\bo@rdframe}{\bo@rdframe[0]}%] +} +% \end{macrocode} +% +% Below is our new implementation of \cs{boardframe}. This is split +% into parts. +% +% +% First, a macro that will define the path around rectangular placed +% hexes. This takes 4 mandatory arguments: lower left column and row, +% and upper right column and row, in that order. It also accepts an +% optional argument. If this is not empty, then it is assumed to be a +% style to apply, and hexes will be drawn using that style. The style +% will be passed the hex coordinates and can react accordingly. +% +% \begin{macrocode} +\def\bo@rdfr@me{ + \@ifnextchar[{\bo@rdfr@me@}{\bo@rdfr@me@[]}%] +} +\def\bo@rdfr@me@u(#1)#2#3#4#5{ + \hex@coords@conv{#1} + % \hex@dbg{0}{#1 -> `\hex@x',`\hex@y'} + \pgfmathparse{min(#2,\hex@x)}\xdef#2{\pgfmathresult} + \pgfmathparse{min(#3,\hex@y)}\xdef#3{\pgfmathresult} + \pgfmathparse{max(#4,\hex@x)}\xdef#4{\pgfmathresult} + \pgfmathparse{max(#5,\hex@y)}\xdef#5{\pgfmathresult} + \hex@dbg{2}{#1 -> ll=`#2',`#3', ur=`#4',`#5'} +} +\def\bo@rdfr@me@[#1]#2#3#4#5{ + % Define rtmp and a ctmp to by directions + \pgfmathparse{int(\hex@coords@row@fac)}\edef\rtmp{\pgfmathresult} + \pgfmathparse{int(\hex@coords@col@fac)}\edef\ctmp{\pgfmathresult} + % Define vertices for path + \def\ctfv{SW} + \def\ctsv{SE} + \def\cbfv{NE} + \def\cbsv{NW} + \def\rrfv{E} + \def\rrsv{NE} + \def\rlfv{W} + \def\rlsv{SW} + % Swap around some definitions based on the row direction + \ifnum\rtmp<0 + \let\max@short\hex@bot@short@col + \let\min@short\hex@top@short@col + \let\swp\ctfv\let\ctfv\cbsv\let\cbsv\swp + \let\swp\ctsv\let\ctsv\cbfv\let\cbfv\swp + \def\rrsv{SE} + \def\rlsv{NW} + \else + \let\max@short\hex@top@short@col + \let\min@short\hex@bot@short@col + \fi + % Swap around some definitions based on the column direction + \ifnum\ctmp<0 + \let\swp\ctfv\let\ctfv\ctsv\let\ctsv\swp + \let\swp\cbfv\let\cbfv\cbsv\let\cbsv\swp + \let\swp\rrfv\let\rrfv\rlsv\let\rlsv\swp + \let\swp\rrsv\let\rrsv\rlfv\let\rlfv\swp + \fi + % Define tmp = 0 if no shorts, 1 if top short, 2 if both + \pgfmathparse{ifthenelse(\hex@got@top@short, + ifthenelse(\hex@got@bot@short,2,1),0)}\edef\tmp{\pgfmathresult} + % If top-short, set factors + \ifnum\tmp=1 + \def\mnf{-1} + \def\mxf{-1} + \def\mnn{} + \def\mxn{} + % If both short, set factors + \else\ifnum\tmp=2 + \def\mnf{\rtmp} + \def\mxf{(-\rtmp)} + % If inverse rows, set factors + \ifnum\rtmp<0 + \def\mnn{} + \def\mxn{not} + \else + \def\mnn{not} + \def\mxn{} + \fi + % If none is short + \else + \def\mnf{1} + \def\mxf{1} + \def\mnn{not} + \def\mxn{not} + \fi\fi + % Define row@mn to give least row of column + \def\row@mn##1{% + \pgfmathparse{int(#3+\mnf* + \hex@coords@row@fac*\min@short(##1)* + \mnn(\min@short(\hex@coords@col@off)))} + \edef\lr{\pgfmathresult}} + % Define row@mx to give largest row of column + \def\row@mx##1{% + \pgfmathparse{int(#5+\mxf* + \hex@coords@row@fac*\max@short(##1)* + \mxn(\max@short(\hex@coords@col@off)))} + \edef\ur{\pgfmathresult}} + % + % + % Below defines a path around the perimeter of the hexes. + % + \def\@llx{10000} + \def\@lly{10000} + \def\@urx{-10000} + \def\@ury{-10000} + % Start with an empty path + \def\p{} + % Loop across least row (can be top if \rtmp<0) + \foreach \c in {#2,...,#4}{% + \row@mn{\c} + \row@mx{\c} + % \message{^^JColumn: `\c' -> `\lr',`\ur' (#3,#5)} + } + \foreach \c in {#2,...,#4}{% + \row@mn{\c} + \xdef\p{\p + (hex cs:c=\c,r=\lr,v=\ctfv)-- + (hex cs:c=\c,r=\lr,v=\ctsv)--} + \bo@rdfr@me@u(c=\c,r=\lr,v=\ctfv)\@llx\@lly\@urx\@ury + \bo@rdfr@me@u(c=\c,r=\lr,v=\ctsv)\@llx\@lly\@urx\@ury + } + % Go up (down if \rtmp<0) right side + \row@mn{#4} + \row@mx{#4} + \foreach \r in {\lr,...,\ur}{% + \xdef\p{\p + (hex cs:c=#4,r=\r,v=\rrfv)-- + (hex cs:c=#4,r=\r,v=\rrsv)--} + \bo@rdfr@me@u(c=#4,r=\r,v=\rrfv)\@llx\@lly\@urx\@ury + \bo@rdfr@me@u(c=#4,r=\r,v=\rrsv)\@llx\@lly\@urx\@ury + } + % Go across largest row (can be bottom if \rtmp<0) + \foreach \c in {#4,...,#2}{% + \row@mx{\c} + % \message{^^JColumn: `\c', max:`\ur'} + \xdef\p{\p + (hex cs:c=\c,r=\ur,v=\cbfv)-- + (hex cs:c=\c,r=\ur,v=\cbsv)--} + \bo@rdfr@me@u(c=\c,r=\ur,v=\cbfv)\@llx\@lly\@urx\@ury + \bo@rdfr@me@u(c=\c,r=\ur,v=\cbsv)\@llx\@lly\@urx\@ury + } + % Go up (down if \rtmp<0) left side. + \row@mn{#2} + \row@mx{#2} + \foreach \r in {\ur,...,\lr}{% + \xdef\p{\p + (hex cs:c=#2,r=\r,v=\rlfv)-- + (hex cs:c=#2,r=\r,v=\rlsv)--} + \bo@rdfr@me@u(c=#2,r=\r,v=\rlfv)\@llx\@lly\@urx\@ury + \bo@rdfr@me@u(c=#2,r=\r,v=\rlsv)\@llx\@lly\@urx\@ury + } + % End path with cycle + \edef\p{\p cycle} + % Define global path + \global\let\hex@board@path\p + \hex@dbg{3}{Hex board path: `\meaning\hex@board@path'} + % If an optional argument was given, then use that to actually make + % hexes. + \ifx|#1|\else + \foreach[count=\nc] \c in {#2,...,#4}{% + \row@mn{\c} + \row@mx{\c} + \foreach \r in {\lr,...,\ur}{% + \hex[#1={\c,\r}](c=\c,r=\r) + } + } + \fi +} +% \end{macrocode} +% +% +% This is a no operations style used as default for the macro +% \cs{boardhexes} below. +% +% \begin{macrocode} +\tikzset{% + /hex/board/no op/.style args={#1,#2}{}} +% \end{macrocode} +% +% This macro will make the actual hexes using the specified, optional, +% style. It builds on \cs{bo@rdfr@me} above. +% +% \begin{macrocode} +\def\boardhexes{% + \@ifnextchar[{\bo@rdhexes}{\bo@rdhexes[board/no op]}%] } +\def\bo@rdhexes[#1](#2)(#3){% + \hex@coords@conv{#2} + \edef\llc{\hex@col} + \edef\llr{\hex@row} + \hex@coords@conv{#3} + \edef\urc{\hex@col} + \edef\urr{\hex@row} + \bo@rdfr@me[#1]{\llc}{\llr}{\urc}{\urr}} +% \end{macrocode} +% +% Creates a board frame using \cs{bo@rdfr@me}. +% +% \begin{macrocode} +\tikzset{board frame bb/.code={ + \pgfkeys{ + %/tikz/local bounding box=tmp board frame, + /tikz/transform shape, + /tikz/execute at end scope={% + % \hex@dbg{1}{Getting board frame BB} + %\wg@get@bb{tmp board frame} + \global\let\llx\@llx + \global\let\lly\@lly + \global\let\urx\@urx + \global\let\ury\@ury + % \hex@dbg{0}{Board bounding box (\llx,\lly)x(\urx,\ury)} + }}}} + \def\bo@rdframe[#1](#2)(#3){% \hex@coords@conv{#2} - \edef\llx{\hex@x} - \edef\lly{\hex@y} \edef\llc{\hex@col} \edef\llr{\hex@row} - \edef\ellc{\hex@eff@col} - \edef\ellr{\hex@eff@row} % \hex@coords@conv{#3} - \edef\urx{\hex@x} - \edef\ury{\hex@y} \edef\urc{\hex@col} \edef\urr{\hex@row} - \edef\eurc{\hex@eff@col} - \edef\eurr{\hex@eff@row} % \def\margin{#1} % - \hex@dbg{2}{% - Board Hex range: (\llc,\llr)x(\urc,\urr) - ^^JEffective range: (\ellc,\ellr)x(\eurc,\eurr) - ^^JBB: (\llx,\lly)x(\urx,\ury)}% - \ifnum\hexdbglvl>1 - %\draw[red,very thick](hex cs:c=\llc,r=\llr) rectangle(hex cs:c=\urc,r=\urr); - \draw[red,ultra thick,dashed](\llx,\lly) rectangle(\urx,\ury); - \draw[->,very thick,blue] (0,0) -- (0,1) (0,0) -- (1,0); - \fi - % Calculate how many half hex hides to add to the "bottom" + % This will store the bounding box in tmp node `board frame' + \bo@rdfr@me{\llc}{\llr}{\urc}{\urr}% + \begin{scope}[board frame bb] + \expandafter\path\hex@board@path; + \end{scope} + \hex@dbg{1}{Board frame LL: -> `\llx',`\lly'} + \pgfmathparse{\llx+ifthenelse(\llx<0,-1,1)*\margin}\edef\llx{\pgfmathresult} + \pgfmathparse{\lly+ifthenelse(\lly<0,-1,1)*\margin}\edef\lly{\pgfmathresult} % - \def\oddeven{isodd} - \ifnum\hex@coords@row@fac<0\def\oddeven{iseven}\fi% - \pgfmathparse{ - ifthenelse(\hex@got@bot@short(\ellc), - ifthenelse(\hex@bot@short@col(\llc)*not(\oddeven(\ellc)),2, - ifthenelse(\hex@bot@short@col(\llc),0,1)), - ifthenelse(\oddeven(\ellc),1,2))} - \edef\olly{\pgfmathresult}% - \hex@dbg{2}{Delta lly: \olly half heights} - % Calculate how many half hex heights to add to the "top" - \def\oddeven{iseven} - \ifnum\hex@coords@row@fac<0\def\oddeven{isodd}\fi% + \hex@dbg{1}{Board frame UR: -> `\urx',`\ury'} + \pgfmathparse{\urx+ifthenelse(\urx<0,-1,1)*\margin}\edef\urx{\pgfmathresult} + \pgfmathparse{\ury+ifthenelse(\ury<0,-1,1)*\margin}\edef\ury{\pgfmathresult} % - \pgfmathparse{ - ifthenelse(\hex@got@top@short(\urc), - ifthenelse(\hex@top@short@col(\urc)*\oddeven(\eurc),0, - ifthenelse(\hex@top@short@col(\urc),2,1)), - ifthenelse(\oddeven(\eurc),1,2))} - \edef\oury{\pgfmathresult}% - \hex@dbg{2}{Delta ury: \oury half heights} - % Calculate new LLY and URY - \pgfmathparse{\lly-\hex@coords@row@fac*(\olly*\hex@yy+\margin)} - \edef\lly{\pgfmathresult} - \pgfmathparse{\ury+\hex@coords@row@fac*(\oury*\hex@yy+\margin)} - \edef\ury{\pgfmathresult} - % Calculate new LLX and URX - \pgfmathparse{\llx-1-\margin}\edef\llx{\pgfmathresult} - \pgfmathparse{\urx+1+\margin}\edef\urx{\pgfmathresult} - % Calculate width and height \pgfmathparse{\urx-\llx}\edef\w{\pgfmathresult} \pgfmathparse{\ury-\lly}\edef\h{\pgfmathresult} + %% Print to the log \hex@dbg{0}{Board Frame: (\llx,\lly)x(\urx,\ury) (\w x\h) (\llc,\llr)x(\urc,\urr)} + %% Possibly draw \draw[hex/board frame/.try](\llx,\lly) rectangle(\urx,\ury); + %% Store macros \xdef\boardXmin{\llx}% \xdef\boardYmin{\lly}% \xdef\boardXmax{\urx}% \xdef\boardYmax{\ury}% -} - +} % \end{macrocode} +% % \end{Macro} % % \begin{Macro}{\boardclip} @@ -104,108 +283,28 @@ % \cs{boardclip}\marg{nx}\marg{ny}\marg{preaction} % \end{Syntax} % \begin{macrocode} -\def\boardpath(#1)(#2){% +\def\boardpath(#1)(#2){ \hex@coords@reset% \tikzset{/hex/coords/.cd, #1} - \edef\llx{\hex@col} - \edef\lly{\hex@row} + \edef\llc{\hex@col} + \edef\llr{\hex@row} %% \hex@coords@reset% \tikzset{/hex/coords/.cd, #2} - \edef\urx{\hex@col} - \edef\ury{\hex@row} - \let\board@odd\@undefined% - \hex@dbg{1}{Board BB in hex: (\llx,\lly)x(\urx,\ury)} - %% - \def\fv{south} - \def\sv{north} - \ifnum\hex@coords@row@fac<0 - \def\fv{north} - \def\sv{south} - \fi - - \edef\hex@board@path{(hex cs:c=\llx,r=\lly,v=\fv\space west)} - %% First the left side - \foreach \r in {\lly,...,\ury} {% - \edef\t{ - --(hex cs:c=\llx,r=\r,v=west) - --(hex cs:c=\llx,r=\r,v=\sv\space west)} - \wg@addto@macro{\hex@board@path}{\t}} - %% Then for top of board - \foreach \c in {\llx,...,\urx} {% - % To be done - %\pgfmathparse{int(ifthenelse(\hex@bot@short@col(\c),1,0))} - %\edef\tmp{\pgfmathresult} - %\ifnum\tmp>0 - %\edef\t{ - % --(hex cs:c=\c,r=\ury,v=\sv\space west) - % --(hex cs:c=\c,r=\ury,v=\sv\space east)} - %\else - \edef\t{ - --(hex cs:c=\c,r=\ury,v=\fv\space east) - --(hex cs:c=\c,r=\ury,v=\fv\space west)} - %\fi - \wg@addto@macro{\hex@board@path}{\t}} - %% Then for right of board - \foreach \r in {\ury,...,\lly} {% - \edef\t{ - --(hex cs:c=\urx,r=\r,v=east) - --(hex cs:c=\urx,r=\r,v=\fv\space east)} - \wg@addto@macro{\hex@board@path}{\t}} - - %% Then for bottom of board - \edef\t{--(hex cs:r=\lly,c=\urx,v=\fv\space west)} - \wg@addto@macro{\hex@board@path}{\t} - \foreach \c in {\urx,...,\llx} {% - \pgfmathparse{int(ifthenelse(\hex@bot@short@col(\c),1,0))} - \edef\tmp{\pgfmathresult} - \ifnum\tmp>0 - \edef\t{ - --(hex cs:c=\c,r=\lly,v=\sv\space east) - --(hex cs:c=\c,r=\lly,v=\sv\space west)} - \else - \edef\t{ - --(hex cs:c=\c,r=\lly,v=\fv\space east) - --(hex cs:c=\c,r=\lly,v=\fv\space west)} - \fi - \wg@addto@macro{\hex@board@path}{\t}} - - \def\t{--cycle} - \wg@addto@macro{\hex@board@path}{\t} + \edef\urc{\hex@col} + \edef\urr{\hex@row} + + % This will store the bounding box in tmp node `board frame' + \bo@rdfr@me{\llc}{\llr}{\urc}{\urr}% + %% Use the path to extract the bounding box + %\begin{scope}[local bounding box=board frame] + % \expandafter\path\hex@board@path; + %\end{scope} \global\let\hexboardpath\hex@board@path } -%\def\boardclip#1#2#3{% -% \pgfmathparse{int(#1-1)}\xdef\board@range{\pgfmathresult,...,0}% -% %% \show\board@range -% \draw \ifx|#3|\else[preaction={#3}]\fi% -% [clip] -% % [decorate,decoration={show path construction, -% % moveto code={\fill[red](\tikzinputsegmentfirst) circle(2pt) -% % node [fill=none,below]{moveto};}, -% % lineto code={\draw[thick,blue,->](\tikzinputsegmentfirst)-- -% % (\tikzinputsegmentlast) node [above] {lineto};}, -% % curveto code={\draw[thick,green,->](\tikzinputsegmentfirst).. -% % controls(\tikzinputsegmentsupporta) and -% % (\tikzinputsegmentsupportb) -% % ..(\tikzinputsegmentlast) node[above]{curveto};}, -% % closepath code={\draw[thick,orange,->](\tikzinputsegmentfirst)-- -% % (\tikzinputsegmentlast) node [above] {closepath};} -% % }] -% (hex cs:r=0,c=0,v=south west) -% %% First the left side -% \foreach \r in {0,1,...,#2} {% -% --(hex cs:c=0,r=\r,v=west)--(hex cs:c=0,r=\r,v=north west)} -% %% Then for top of board -% \foreach \c in {0,1,...,#1} {% -% --(hex cs:r=#2,c=\c,v=north west)--(hex cs:c=\c,r=#2,v=north east)} -% %% Then for right of board -% \foreach \r in {#2,...,0} {% -% --(hex cs:c=#1,r=\r,v=east)--(hex cs:c=#1,r=\r,v=south east)} -% %% Then for bottom of board -% --(hex cs:r=0,c=#1,v=south west) \foreach \c in \board@range {% -% --(hex cs:r=0,c=\c,v=south east) --(hex cs:c=\c,r=0,v=south west) } -% --cycle; } -%% New definition - much simpler + +% \end{macrocode} +% \begin{macrocode} \def\boardclip(#1)(#2)#3{% \boardpath(#1)(#2) \draw \ifx|#3|\else[preaction={#3}]\fi% |