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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a set of arrows that intersect a circle and I want to highlight all intersections dynamically. I know that I can find those intersections via tikz' name intersections but I can't get it to work.

This is what I got so far:

Rays and circle without intersections

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,intersections}
\begin{document}
\begin{tikzpicture}
 \node[shape=circle,draw] (eye) {};
 \draw[name path=circle1] (5,0) circle (1);
 \foreach \i in {-5, ..., 5} {
  \node[draw, inner sep=0, minimum height=0.25cm,minimum width=0.05cm] at (4,0.25 * \i) (pixel-\i) {};
  \draw[name path={ray-\i}, -latex,shorten >=-5cm] (eye) -- (pixel-\i);
  \fill[name intersections={of={ray-\i} and circle1,name=int,total=\t}]
      \foreach \s in {1,...,\t} (int-\s) coordinate [mark coordinate=red];
 }
\end{tikzpicture}
\end{document}

when I try to run this I get the error

Package pgf Error: No shape named int-1 is known.

One problem is that there might not be any intersection for an arrow but I don't know how to make \foreach do nothing in this case.

share|improve this question

Apparently Tikz doesn't like when you extend the lines artificially using shorten >=-5cm so that's the problem. Your lines don't actually reach the circle, so there are no intersections.

This is solved by either placing the nodes behind the circle or drawing the lines independently from the nodes.

Here's a slightly different version of your code (which didn't result in your image anyways). I gave the nodes the name pixel-\xi because this one is the counter from 1 so the nodes have more proper names like pixel-1 whereas using \i, you'd have something like pixel--5 and then pixel-5.

Output

enter image description here

Code

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}
\begin{tikzpicture}
\node[circle,draw] (eye) at (0,0) {};
\draw[name path=circle1] (5,0) circle (1cm);
\foreach \i [count=\xi, evaluate=\xi as \angle using int(12-(\xi*2))] in {-5,...,5}{%
\node[draw, inner sep=0pt, minimum height=.1cm,minimum width=.05cm] at (3.5,\i*.1) (pixel-\xi) {};
\draw[-latex,name path={ray\xi}] (eye) -- (\angle:7cm);
\fill[red,name intersections={of={ray\xi} and circle1, name=i, total=\t}]
    \foreach \s in {1,...,\t}{(i-\s) circle (1pt)};
}
\end{tikzpicture}
\end{document}
share|improve this answer
    
While I suspected that, it does not solve the problem of arrows that "miss" the circle which I was asking specifically about. – Nobody Mar 2 at 9:12
    
@Nobody I see, however your code doesn't give me the result you present in your question. I'll present an alternative version with "missing" circles and edit the answer as soon as I can. :) – Alenanno Mar 2 at 9:16
    
Sorry about the confusion, I thought I'd add the image as well after I had already pasted the code and played with it before posting it. I updated the code to reflect what the image is like. (Obviously, without the intersections) – Nobody Mar 2 at 9:19
    
@Nobody No problem! And thank you. I'll grab it then. – Alenanno Mar 2 at 9:20

You can also use the calc library to extend lines. Note that when \t=0 the \foreach will still execute \s=1, hence the \ifnum ... \fi test.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,intersections,calc}
\begin{document}
\begin{tikzpicture}
 \node[shape=circle,draw] (eye) {};
 \draw[name path=circle1] (5,0) circle (1);
 \foreach \i in {-5, ..., 5} {
  \node[draw, inner sep=0, minimum height=0.1cm,minimum width=0.05cm] at (4,0.2 * \i) (pixel\i) {};
  \draw[name path={ray\i}, -latex] (eye) -- ($(eye)!2!(pixel\i)$);
  \fill[red,name intersections={of={ray\i} and circle1,name=int,total=\t}]
    \ifnum \t>0 \foreach \s in {1,...,\t} {(int-\s) circle (1pt)}
    \fi;
 }
\end{tikzpicture}
\end{document}

intersections

share|improve this answer
    
I was afraid that I had to do exactly this. I'd hoped there was some syntax to make foreach do no iterations at all. – Nobody Mar 2 at 9:14
    
Nothing says a \foreach has to go from small to large. In fact, \foreach \s-{1,...,0} should do both \s=1 and \s=0. – John Kormylo Mar 2 at 18:33

As Alenanno explained, TiKZ doesn't like to use negatively extended paths for computing intersections. What can be done is use calc library to draw all rays with their exact angle. And as all of them intersect with right hand circle, the problem with missing intersection point disappear:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{ifthen}
\usetikzlibrary{shapes,intersections,calc}
\begin{document}
\begin{tikzpicture}
 \node[shape=circle,draw] (eye) {};
 \draw[name path=circle1] (5,0) circle (1);
 \foreach \i in {-5, ..., 5} {
  \node[draw, inner sep=0, minimum height=0.1cm, minimum width=0.05cm] 
        at (4,0.1 * \i) (pixel-\i) {};
  \draw[name path={ray-\i}, -latex]
    let 
        \p1=($(pixel-\i)-(eye)$), \n1={atan2(\y1,\x1)}
    in
        (eye)--++(\n1:6.5cm);
  \fill[red, name intersections={of={ray-\i} and circle1, name=int, total=\t}]
    \foreach \s in {1,...,\t} {(int-\s) circle(1pt)};
 }
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer

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.