How to horizontally draw a line passing through a point A until it reaches the border of a node B using TikZ?

Given point A and a node B with an ellipse shape, how to draw a line from A horizontally until it reaches the border of B?

-
Since you have some responses below that seem to answer your question, please consider marking one of them as ‘Accepted’ by clicking on the tickmark below their vote count. This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). –  Martin Scharrer May 30 '11 at 16:38

One way is to use the intersection library:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
\coordinate[label=left:$A$] (A) at (0,0);
\coordinate[label=center:$B$] (B) at (2,1);

\draw[name path=B node] (B) ellipse (0.5 and 1.2);
\path [name path=A--B] (A) -| (B);
\path [name intersections={of=A--B and B node}];
\fill (A) circle (2pt);
\draw (A)  -- (intersection-1);
\end{tikzpicture}

\end{document}

-
When I compile your example, I see no line drawing from A to B. –  Leo Liu Aug 11 '10 at 18:30
Sorry. I have edited the example and now I have also compiled it... I see a line now. –  Martin Heller Aug 11 '10 at 18:48
That's not horizontal line. I think for what you are doing draw from a point to a node shape automatically stops at the border. But I will take a look at the intersections lib. –  Leo Liu Aug 11 '10 at 19:15
Yes, I think the take home message is the intersections library. I hope that I have corrected my example now. –  Martin Heller Aug 11 '10 at 19:54
Better late than never. –  Martin Heller Aug 11 '10 at 20:03

If you have the intersections library available, I agree that it's the best way to go for this. But versions of TikZ prior to the introduction of intersections (which are apparently fairly common in the wild) didn't have the capability to automatically compute the intersection point between a line and an elliptical node. If it were a circular node, you could do

\begin{tikzpicture}
\node (A) at (0,0) {A};
\node[draw,circle,minimum height=3cm] (B) at (2,1) {B};
\draw (A) -- (intersection cs: first line={(A)--+(10,0)},second node=B,solution=2);
\end{tikzpicture}


but that doesn't work for ellipses. So here are some alternatives.

One option would be to "cheat" by drawing the line before the node, and then filling the node with an opaque color:

\begin{tikzpicture}
\node (A) at (0,0) {A};
\node[ellipse,minimum height=3cm] (B) at (2,1) {};
\draw (A) -- (intersection cs: first line={(A)--+(10,0)},second line={(B.center)--(B.south)});
\node[fill=white,draw,ellipse,minimum height=3cm] at (B) {B};
\end{tikzpicture}


but this is highly undesirable because it requires you to specify the same node twice.

A slightly better (but still not ideal) option is to use TikZ to manually calculate the proper position for the line to end.

\begin{tikzpicture}
\node (A) at (0,0) {A};
\node[draw,ellipse,minimum height=3cm] (B) at (2,1) {B};
\newdimen\semimajor
\newdimen\semiminor
\newdimen\ydiff
\pgfextracty{\semimajor}{\pgfpointdiff{\pgfpointanchor{B}{south}}{\pgfpointanchor{B}{center}}}
\pgfextractx{\semiminor}{\pgfpointdiff{\pgfpointanchor{B}{west}}{\pgfpointanchor{B}{center}}}
\pgfextracty{\ydiff}{\pgfpointdiff{\pgfpointanchor{A}{center}}{\pgfpointanchor{B}{center}}}
\pgfmathparse{\semiminor * sqrt(1 - pow(\ydiff / \semimajor,2))};
\draw (B.center) ++(-\pgfmathresult pt,-\ydiff) -- (A);
\end{tikzpicture}

-
Thanks for that but I think intersections is the way to go. –  Leo Liu Aug 11 '10 at 20:53
I'd agree, if you have access to it. (I don't) –  David Z Aug 11 '10 at 21:29
By the way, an explanation from whoever case the downvote would be much appreciated. –  David Z Aug 11 '10 at 21:30
The TikZ intersections library can be used to find intersection points between a line and an elliptical node: \documentclass{article} \usepackage{tikz} \usetikzlibrary{intersections} \usetikzlibrary{shapes.geometric} \begin{document} \begin{tikzpicture} \node (X)[draw,shape=ellipse,minimum height=3cm,name path=X] at (0,0) {x}; \draw[name path=L] (-2,0) -- (2,0); \path[name intersections={of=X and L}]; \fill[red] (intersection-1) circle (2pt); \fill[blue] (intersection-2) circle (2pt); \end{tikzpicture} \end{document} –  Martin Heller Aug 11 '10 at 22:46
@Martin: I saw your answer. Why did you repost the code sample in a comment? –  David Z Aug 12 '10 at 4:24

It's a little late, but I stumbled upon this, and the intersections machinery is overkill. You can just specify the anchor you want the line to go to, like so:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\begin{document}

\begin{tikzpicture}
\node [label=south:$A$] (A) at (0,0) {};
\filldraw (A) circle (1pt) ;
\node [draw, ellipse, minimum height = 2cm] (B) at (2,0) {B};

\draw [red] (A.center) -- (B.east) ;
\end{tikzpicture}

\end{document}


This produces the following image:

If you want the line to go to the left side, replace (B.east) with (B.west). If you want it to go elsewhere, you can use the anchor (B.θ), where θ is an integer between 0 and 360; 0 corresponds to east, and adding one moves the anchor around the node boundary by one degree.

-
The disadvantage of this approach is that then it might be difficult to obtain a line that is really horizontal, let's say if the node A was a little lower. –  Hendrik Vogt Nov 12 '10 at 17:05
Hmm, yes, didn't think of that. It depends on whether or not your goal is "line to here" or "precisely horizontal line". This works for the former, but you do need intersections for the latter. –  Antal S-Z Nov 12 '10 at 17:25