Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

\foreach behavior inside a \draw #1303

Open
alceu-frigeri opened this issue Jan 8, 2024 · 4 comments
Open

\foreach behavior inside a \draw #1303

alceu-frigeri opened this issue Jan 8, 2024 · 4 comments
Labels

Comments

@alceu-frigeri
Copy link

alceu-frigeri commented Jan 8, 2024

Brief outline of the bug

Hi,
I don't know if it qualifies as a bug, or a misunderstanding of mine about how a foreach should work, when used inside a path.
From my understanding, section 88 of the manual (pages 1001+), the foreach should just, mainly, expands the code inside the braces (if there is one, replacing the variables of the foreach).
In the example below, my understanding was that the 3 cases (commented out) should be equivalent. producing a line from (X) to node (nA) node (nB) and finally coordinate (X).
case (1), the simplest, does just that, connecting the arcs (at node nA and node nB) as expected.
case (2), 'does the job', by means of three \draw commands
\draw (X) -- (nA) ; \draw (nA) -- (nB); \draw (nB) -- (X)

case (3) was the surprise for me, I expected it to be equivalent too (well, to be equal to case (1)) .. but I got a continuous line from (X) to (Y) ignoring the nodes (arcs) dimensions.

Is that the expected behavior? what am I missing on it? or is it a foreach miss behavior ?

For a better context: I'm using this construct with coordinates obtained from \draw[name intersections={of=...
(intersections library). So I'm forced to use foreach statements to connect the many 'intersection' coordinates, in which I place an arc node in each intersection.

In my use case what I have implemented, for now, is a workaround based on case (2), better said, from the intersection coordinate/nodes list I generate a clist of node-pairs then I execute a final foreach with said list.

 \gdef\@tmpA{#3}
  \gdef\@ListA{}
  \foreach \x in {1,...,\csuse{#2T}} {\xappto{\@ListA}{\@tmpA/n#2-\x,}\xdef\@tmpA{n#2-\x}}
  \xappto{\@ListA}{n#2-\csuse{#2T}/#4}
  \foreach \xa/\xb in \@ListA {\draw[line cap=round] (\xa) -- (\xb);}

(that's just to have an idea what I ended doing, #3would be X, #4 would be Y, #2T is the macro name with the number of intersections.. the n#2-\x are the intersection node names. It works, just fine, but it would be nicer not to have to use such a construct to just connect the nodes, and be able, for instance, to have something like

\draw (#3) \foreach \x in {1,...,\csuse{#2T}} { -- (\x) } -- (#4) ;

Minimal working example (MWE)

\documentclass{article}
\usepackage{tikz}

%%% This is just to make the page tight... not needed for the MWE
%\usepackage[active,tightpage]{preview}
%\PreviewEnvironment{tikzpicture}
%\setlength\PreviewBorder{5pt}%



\begin{document}

\begin{tikzpicture}
  \path 
    (0,0) coordinate(X) 
    (1,1) coordinate(A) node[minimum size=4.3pt,inner sep=0pt](nA){}
    (2,2) coordinate(B) node[minimum size=4.3pt,inner sep=0pt](nB){}
    (3,3) coordinate(Y)
    ;
  \draw[rotate=45] 
    (A) +(-7pt/2,0) arc[start angle=180,end angle=0,radius=7pt/2]
    (B) +(-7pt/2,0) arc[start angle=180,end angle=0,radius=7pt/2]
    ;
    
    % Case (1)
  %\draw (X) -- (nA) -- (nB) -- (Y) ;
  
    % Case (2)
  %\foreach \x/\y in {X/nA,nA/nB,nB/Y} {\draw (\x) -- (\y);}

    % Case (3)
  %\draw (X) \foreach \x in {nA,nB,Y} { -- (\x)};
  
\end{tikzpicture}

\end{document}
@loopspace
Copy link
Contributor

The issue appears to be that the \tikz@moveto@waiting is not part of the suite that TikZ remembers from one iterate of a foreach to the next. More details, and a suggested fix, can be found at https://tex.stackexchange.com/a/706676/86

(Once I've updated my local version of PGF then I can create a pull request for this, but I've only tested it with the broken code so haven't verified that it doesn't break anything else.)

loopspace added a commit to loopspace/pgf that referenced this issue Jan 8, 2024
In the code:

```
\draw (A) foreach \nd in {B,C} { -- (\nd) };
```
then the line to `C` is drawn from `A`, not `B`.  This is because the
foreach loop does not update the macro that remembers that the last
coordinate was a node.  This fixes that issue.

See pgf-tikz#1303
@alceu-frigeri
Copy link
Author

Thanks again for your reply.
A note, though, a just took a second look on an example from the manual, page 1003.

\tikz
\draw (0,0)
foreach \x in {1,...,3} { -- (\x,1) -- (\x,0) };

Which works as one would expect, I mean, connecting (0,0) -- (1,1) -- (1,0) -- (2,1) -- (2,0) -- (3,1) -- (3,).
I mean, the (miss) behavior was due the using of nodes, and not coordinates.

@muzimuzhi
Copy link
Member

The issue appears to be that the \tikz@moveto@waiting is not part of the suite that TikZ remembers from one iterate of a foreach to the next.

Similar: #1047, in which \tikz@tagent was found to be not remembered by foreach path operation.

@loopspace
Copy link
Contributor

loopspace commented Jan 11, 2024

I've refactored my fix to make it more extendible, and included \tikz@tangent and \tikztostart in the list.

loopspace added a commit to loopspace/pgf that referenced this issue Apr 2, 2024
In the code:

```
\draw (A) foreach \nd in {B,C} { -- (\nd) };
```
then the line to `C` is drawn from `A`, not `B`.  This is because the
foreach loop does not update the macro that remembers that the last
coordinate was a node.  This fixes that issue.

See pgf-tikz#1303

Signed-off-by: Andrew Stacey <loopspace@mathforge.org>
loopspace added a commit to loopspace/pgf that referenced this issue Apr 12, 2024
This commit adds more information to what TikZ remembers between foreach
iterations, and does so in a way that makes it easier to add other
macros and dimensions to the list of things it remembers, both at the
code level and via keys.

Fixes pgf-tikz#356, pgf-tikz#1047, pgf-tikz#1303, pgf-tikz#1313

Signed-off-by: Andrew Stacey <loopspace@mathforge.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

3 participants