summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/wargame/source/hex/board.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/wargame/source/hex/board.dtx')
-rw-r--r--macros/latex/contrib/wargame/source/hex/board.dtx393
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%