2

In the picture below, I want to draw the horizontal line up to the abscissa x=3.
How can I easily do that, without explicitly defining the point where the line breaks (i.e. the "--++(45:.5)" point)?

enter image description here

Here are possible solutions I know, but they are not satisfactory (since too complicated):

  • I could define an intersection using the intersections library and the vertical line (3,-10) -- (3,10), but it seems an overkill, and messes up the bounding box (I could add a \clip... but it would make the code even bulkier);
  • I could draw the line \draw (45:.75) ++ (45:.5) -| ++(2,0);, and define a new coordinate at the angle using [pos=.5]. But again, it seems to be to much work for that.

\documentclass[border=10pt]{standalone}
    \usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \fill [gray] (0,0) circle [radius=1];
        \draw [<-] (45:.75) -- ++ (45:.5) -- ++(2,0);

        %== below are just 'decoration' to make the picture more obvious ==%
        \draw [help lines] (-1.5,-1.5) grid (3.5,1.5);
        \path [font=\tiny, text=blue] (45:.75) node [left]{\verb|\path (45:.75)|}
            -- ++ (45:.5) node [above] {\verb|-- ++ (45:.5)|}
            -- ++(2,0) node [above] {\verb|-- ++(2,0);|};
        \foreach \x in {-1, ..., 3}{
            \node [below] at (\x,0) {\x};
        }
    \end{tikzpicture}
\end{document}
  • but then you have to change the decoration ++(2,0) because there is more then 2cm to reach there is that correct? – percusse Dec 8 '16 at 10:57
  • Yes! of course, the -- ++(2,0) is what have to be changed. – ebosi Dec 8 '16 at 10:59
  • 1
    Then \draw [<-] (45:.75) -- ++ (45:.5) coordinate (a) -- (a-| {(3,0)}); would do it – percusse Dec 8 '16 at 11:04
  • @percusse yes it does: this is the writing I was looking for! // And what if I want to align the line break (i.e. the start of the horizontal line) with the abscissa x=1 - without know it should then be a (1,1)? [I know it was not in the first question, sorry] – ebosi Dec 8 '16 at 11:12
  • That's trickier because the path length and the end point is unknown simultaneously. Then you need extras as you mentioned or calculate the hypotenuse with let... in and so on. – percusse Dec 8 '16 at 11:23
2

The basic idea is to use the A -| B operator to compute the position of the point positioned on the abscissa of B and on the coordinate of A. (Note that you can use A |- B for the opposite.)

So you can use either of these solutions:

\draw [<-] (45:.75) -- ++ (45:.5) coordinate (a) -- (a-| {(3,0)});
% OR %
\usetikzlibrary{calc}
\draw [<-] (45:.75) -- ++ (45:.5) -- ({$(45:.75) + (45:.5)$} -| {(3,0)});

The first creates a local coordinate (a) on the fly where the arrow breaks. The second re-computes the position of the angle (i.e. coordinate of the starting point + shift to the angle-point).


If you plan to do this a lot, you can create a macro to do all the work.

\documentclass[border=10pt]{standalone}
    \usepackage{tikz}
        \usetikzlibrary{calc}

\newcommand{\angled}[3][]% #1=draw options (optional), #2=start, #3=end, use tikz point notation inside braces
{\bgroup% local macros
  \path #2;
  \pgfgetlastxy{\xa}{\ya}%
  \path #3;
  \pgfgetlastxy{\xb}{\yb}%
  \pgfmathsetlengthmacro{\xc}{\xb+.707*(\ya-\yb)}%
  \pgfmathsetlengthmacro{\xd}{\xb+.707*(\yb-\ya)}%
  \ifdim \ya>\yb \relax
    \ifdim \xa<\xb \relax \let\xc=\xd \fi
  \else
    \ifdim \xa>\xb \relax \let\xc=\xd \fi
  \fi
  \draw[#1] #2 -- (\xc,\ya) -- #3;
\egroup}

\begin{document}
    \begin{tikzpicture}
        \fill [gray] (0,0) circle [radius=1];
        %\draw [<-] (45:.75) -- ++ (45:.5) -- ++(2,0);
        \angled[->]{(2,1)}{(45:.75)}%

        %== below are just 'decoration' to make the picture more obvious ==%
        \draw [help lines] (-1.5,-1.5) grid (3.5,1.5);
        \path [font=\tiny, text=blue] (45:.75) node [left]{\verb|\path (45:.75)|}
            -- ++ (45:.5) node [above] {\verb|-- ++ (45:.5)|}
            -- ++(2,0) node [above] {\verb|-- ++(2,0);|};
        \foreach \x in {-1, ..., 3}{
            \node [below] at (\x,0) {\x};
        }
    \end{tikzpicture}
\end{document}
  • @ebo - You can provide your own answer, and after a couple of days you can even accept it. – John Kormylo Apr 9 '17 at 20:28
  • You're right. Actually, I hesitated between adding a new answer or updating yours. Indeed, the solution I chose is the one you gave in comments. Since my edit was mainly based on your comment, I though it would be fairer to add details to your answer. But I can understand it might appear a bit weird. – ebosi Apr 9 '17 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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