2

I'm not experienced with LaTeX/TikZ, so I may be doing something dumb.

I have two versions of this code. One works, and one doesn't and I'm at my wits end trying to figure out why the second doesn't.

First, the version that works:

\documentclass[parskip]{scrartcl}
\usepackage[left=1cm, right = 3cm, top = 1cm, bottom = 1cm]{geometry}
\usepackage{tikz}
\usepackage{pifont} 
\usepackage{xifthen}
\usepackage[utf8]{inputenc}
\usepackage{forloop}
\usepackage[nomessages]{fp}


\usetikzlibrary{shapes}
\usetikzlibrary{calc}


\newcommand\sz{1.5cm}

%usage: size guid
\newcommand\hexboard[2]{
\begin{tikzpicture} [hexa/.style= {shape=regular polygon,regular polygon sides=6,minimum size=\sz, draw,inner sep=0,anchor=center,fill=lightgray!85!blue,rotate=0}, remember picture]
    \newcommand\sep{x}
    \pgfmathsetmacro\minCoord{int(-1*#1)} 
    \foreach \j in {\minCoord,...,#1}{% 
        \foreach \i in {\minCoord,...,#1}{%
            \ifthenelse{\cnttest{ \minCoord }{<}{ \i*\j }}{\node[hexa] (#2_h\i\sep\j) at ({(\i*.75*\sz)},{\j*\sz*sqrt(3)/2 - \i*\sz*sqrt(3)/4}) {\i\sep\j};}{}  
        }
    } 
\end{tikzpicture}
}

%usage: {{x1,y1}...} color opacity guid
\newcommand\targetedHexes[4]{
\begin{tikzpicture} [hexa/.style= {fill opacity = #3, shape=regular polygon,regular polygon sides=6,minimum size=\sz, draw,inner sep=0,anchor=center,fill=lightgray!85!blue,rotate=0}, remember picture, overlay]
    \foreach [count=\x] \pt in {#1} {
            \node [hexa, fill = #2] (target\x) at (#4_h\pt) {};
        }
\end{tikzpicture}
}
%usage: guid
\newcommand\drawSelf[1]{
\begin{tikzpicture} [hexa/.style= {fill opacity = .5, shape=regular polygon,regular polygon sides=6,minimum size=\sz, draw,inner sep=0,anchor=center,fill=lightgray!85!blue,rotate=0}, remember picture, overlay]
    \node [hexa, color = blue] (self) at (#1_h0x0){};
\end{tikzpicture}
}

\newcommand\areaEffect[2]{
    \hexboard{#1}{hello}
        \targetedHexes{#2}{red}{0.5}{hello}
    \drawSelf{hello}
}

\begin{document}
\areaEffect{2}{{0x1},{0x2},{1x0}}
\end{document}

Basically, what it does is draws a hex grid, and then overwrites certain hexes (passed in as a list of coordinates) with a different color.

I would like to be able to specify multiple groups, each of which gets a different color/opacity. However, modifying the above to replace the last 10 lines does not work:

\newcommand\areaEffect[2]{
    \hexboard{#1}{hello}
    \foreach [count=\s] \section in {#2}{
            \targetedHexes{\section}{red}{0.15*\s}{hello}
    }
    \drawSelf{hello}
}

\begin{document}
\areaEffect{2}{{{0x1},{0x2}},{{1x0}}}
\end{document}

Specifically, while in the old version, in \targetedHexes, in (target\x) at (#4_h\pt), \pt evaluates to 0x1 or 0x2. In the new version, it evaluates to {0x1} or {0x2}.

I guess my questions are the following:

What's going on here? Why are these different? Shouldn't they be more-or-less equivalent?

How do I fix the second version?

Thank you for your time!

4
  • It's evaluating to {0x1} instead of 0x1 because you're using too many {} when calling \areaEffect, try using: \areaEffect{2}{{0x1},{0x2},{1x0}} instead. Jan 29, 2017 at 11:13
  • Isn't this the common group-problem of \foreach? Jan 29, 2017 at 11:22
  • @GuilhermeZanotelli: What you're suggesting is the way I call it in the first version, which doesn't have the foreach. What I'm trying to do in the second version is call \targetedHexes first on {{0x1},{0x2}}, and then on {{1x0}}.
    – ebdavis
    Jan 29, 2017 at 19:37
  • @Schweinebacke: Possibly? I wouldn't think so, as I'm not trying to draw anything that relies on external state (I think). Why do you think so?
    – ebdavis
    Jan 29, 2017 at 19:43

1 Answer 1

2

In the first version, \targetedHexes is called with {0x1},{0x2},{1x0} as first argument, by ordinary parameter replacement.

In the second version, \targetedHexes is called with \section as the first argument; no expansion takes place at this point. It now depends on the subsequent code whether \section is expanded in time; which it is apparently not.

Expanding \section before calling targetedHexes seems to do the trick.

\newcommand\areaEffect[2]{
    \hexboard{#1}{hello}
    \foreach [count=\s] \section in {#2}{
            \expandafter\targetedHexes\expandafter{\section}{red}{0.15*\s}{hello}
    }
    \drawSelf{hello}
}
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .