Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I need the help of some smart people ;)

I want to draw a picture with TikZ, which is heavily based on randomization and I want to make it quite parametrized. It's actually a graph of n nodes where edges are incident to nodes based on previous node placement, so one can not do it all in only one for-loop, that's not possible (and i need x- and y-coordinates independently). In my plans i store x- and y-coordinates in an array and retrieve the data later for calculations. but I run into problems....

Array usage in TikZ is either limited or badly described (how to store/change data after initialization?) So I use the package arrayjobx. below is a minimal non-working example (from my memory, unfortunately, my coding PC is currently not accessible; but I hope you see the problem without having a 100%-guaranteed compilable example):

\begin{tikzpicture}
\newarray\xcoord
\def \n {5}
\foreach \i in {1,...,\n}
  {
  % roll randomvalues and store them in arrays xcoord
  \pgfmathsetmacro{\xe}{rnd*10}
  \xcoord(\i)={\xe}

  \foreach \j in {1,...,\i}
  {
    % access data in second nested loop; accessing is done with \checkArrayname and \cachedata to avoid parsing errors
    \checkxcoord(\j)
    \let\xf\cachedata
    % next line is just for "debugging"
    \node[draw,circle] at (\i,\j) {\xf};
  }
}
\end{tikzpicture}

I can access the data without problems in the first loop. It's working fine. But in the second nested loop, no matter what value \j should have, \xf gets the value of \xcoord(\i), instead of \xcoord(\j). I tried it in different ways, using a counter for \j, using length-parameters instead of \let, etc. but the result is always the same.

What could cause this behaviour? Does anyone of you know a workaround?

share|improve this question
1  
Welcome to TeX.SE. –  Peter Grill Oct 3 '12 at 9:57
add comment

2 Answers

up vote 3 down vote accepted

An assignment such as

\xcoord{\i}={\xe}

usually loads \xcoord with the macro \xe, not its value (which can change).

If you want to load it with the value of \xe, then say

\begin{tikzpicture}
\newarray\xcoord
\expandarrayelementtrue
\def \n {5}
\foreach \i in {1,...,\n}
  {
  % roll randomvalues and store them in arrays xcoord
  \pgfmathsetmacro{\xe}{rnd*10}
  \xcoord(\i)={\xe}
[...]

The change to the conditional \ifexpandarrayelement will be confined to this tikzpicture (the environment forms a group). If you have other arrayjobx assignments in the environment that mustn't obey to this setting, then put \expandarrayelementtrue inside the \foreach or say \expandarrayelementfalse when you need not to expand.

share|improve this answer
    
hi, many thanks, that solved my problem! (i had plenty of others afterwards, one strikingly similar...) –  dps_kane Oct 4 '12 at 3:46
    
however, though i understood now the difference between value and macro, i don't have an idea when and how to use \expand commands. i'd like to know more, it seems to be key knowledge for me to improve my tikzing capabilities! i tried searching for some explanations with google, but i probably used the wrong keywords, can you give me hint in that matter? latex + expand/expansion/noexpand did not really come up with something.... –  dps_kane Oct 4 '12 at 3:54
add comment

It looks like the result of \xe is not expanded .

\documentclass{standalone}
\usepackage{tikz,arrayjobx}

\begin{document}

\begin{tikzpicture}
\newarray\xcoord
\def \n {5}
\foreach \i in {1,...,\n}
  {
  % roll randomvalues and store them in arrays xcoord
  \pgfmathsetmacro{\xe}{rnd*10}
  \edef\temp{\noexpand\xcoord(\noexpand\i)={\xe}}\temp

  \foreach \j in {1,...,\i}
  {
    \node[draw,circle] at (2*\i,2*\j) {\xcoord(\j)};
  }
}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
i think i had the same problem with a counter (but i am not sure; i solved it by exchanging the counters by 1-element arrays :D) can i use the same method for counters? i mean, the \edef\temp\noexpand.... monster? or do i need a different kind of command if i want a counter to survive correctly through various loops? –  dps_kane Oct 4 '12 at 4:01
    
@dps_kane Usually \the\countername is enough but we need to have an example to be sure. Expansion in TeX is crucial for assignment and you can search for \expandafter on this site or get the famous TeX by Topic and go nuts. Here is a good overview tex.stackexchange.com/questions/451/… –  percusse Oct 4 '12 at 8:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.