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

name intersections with sort-by inside \foreach loop produced wrong intersection as first one #1345

Open
robert-g-liu opened this issue Jul 3, 2024 · 1 comment

Comments

@robert-g-liu
Copy link

robert-g-liu commented Jul 3, 2024

Brief outline of the bug

In below MWE three different coding styles were given for enabling sort-by option in name intersections. The first one didn't work. Not sure why name path {Ray \i} (or {Ray\i}, {Ray-\i}) wasn't accepted in inside a \foreach loop.

BTW, the second code snippet worked though it's sort of bad idea to share the same name path between all rays.

Minimal working example (MWE)

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}[scale=2]

    \draw [name path=Circle] (5,0) circle (2);

    % what'wrong with using {Ray \i}?
    \foreach \i in {1} {
         \draw [thick, name path={Ray \i}] (0, 0) -- (7,2);
         \draw [fill=red, name intersections={of = {Ray \i} and Circle, name=c, sort by={Ray \i}}]
              (c-1) circle (1mm);
    }

    \foreach \i in {1,2} {
         \draw [blue, name path=Ray] (0, 0) -- (7,{0.2*\i+1.3});
         \draw [fill,name intersections={of = Ray and Circle, name=c, sort by=Ray}]
              (c-1) circle (0.5mm);
    }
    
    \draw [name path=Ray X] (0, 0) -- (7,2.5);
    \draw [fill,name intersections={of =  Ray X and Circle, name=c, sort by=Ray X}]
         (c-1) circle (0.5mm);
\end{tikzpicture}
\end{document}
@Qrrbrbirlbel
Copy link
Contributor

Qrrbrbirlbel commented Jul 21, 2024

BTW, the second code snippet worked though it's sort of bad idea to share the same name path between all rays.

In this case, it doesn't really matter because the path is only available for that iteration of the loop.

But that's no excuse for the apparent bug.


The problem comes from expansion.
For the of key, the path names do not get fully expanded:

\def\tikz@intersect@path@names@parse#1 and #2\tikz@stop{%
\def\tikz@intersect@path@a{#1}%
\def\tikz@intersect@path@b{#2}%
}%

while for the sort by key ithe given argument gets expanded:
sort by/.code=\edef\tikz@intersect@sort@by{#1}\tikz@intersect@check@sort@by%

The code compares a macro that expands to Ray 1 with a macro that expands to \Ray \i and the sorting will fall back to no sorting.

So, as a workaround, you can do of/.expanded = {Ray \i} and Circle or we fix the of key:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\makeatletter
\tikzset{
  intersection/of/.code args={#1 and #2}{%
    \edef\tikz@intersect@path@a{#1}%
    \edef\tikz@intersect@path@b{#2}}}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=2]
\draw [name path=Circle] (5,0) circle (2);
\foreach \i in {1} {
  \draw [thick, name path={Ray \i}] (0, 0) -- (7,2);
  \draw [fill=red, name intersections={of = {Ray \i} and Circle, name=c, sort by={Ray \i}}]
    (c-1) circle (1mm);
}
\end{tikzpicture}
\end{document}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants