# angled lines of unkown length in TikZ

I am trying to create angled lines from a point to specific border. Here is a minimal example:

\documentclass[margin=2mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0, 0);
\coordinate (B) at (5, 0);
\coordinate (C) at (5, -5);
\coordinate (D) at (1, -4);
\clip (A) rectangle (C);
\draw (A) -- (B) -- (C);
\foreach \a in {10,30,...,70}{
\draw (D) -- +(\a:3);
}
\end{tikzpicture}
\end{document}


How do I set the length of these lines? 3 is to short. Setting the value to 10 solves the problem. However, resizing A, B and C gives the same problem. Is it possible to draw the lines until they hit a border? Or can I calculate a length in TikZ? I only know the calculation of points, but here I need a length.

Here a suggestion where you compute the maximum distance between coordinates.

The function \MaxNodeDistance has two mandatory arguments. The first argument is the reference point. The second argument can be a list with defined coordinates. The result of the function is the macro \Distance.

The command \gettikxy is taken from https://tex.stackexchange.com/a/33765/5239

To demonstrate the command I change the command clip to draw and add the angle 45 which is the maximum distance.

\documentclass[margin=2mm]{standalone}
\usepackage{tikz}
\usepackage{xparse}
\ExplSyntaxOn
\makeatletter
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\makeatother
\NewDocumentCommand \MaxNodeDistance { m >{ \SplitList { , } } m }
{
\def\Distance{0pt}
\gettikzxy{(#1)}{\xa}{\ya}
\ProcessList {#2} { \dirk_nodedistance_aux:n }
%  \Distance
}
\cs_new:Npn  \dirk_nodedistance_aux:n #1
{
\gettikzxy{(#1)}{\xb}{\yb}
\pgfmathparse{max( (veclen(\xa-\xb,\ya-\yb)) ,\Distance }
\edef\Distance{\pgfmathresult pt}
}
\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0, 0);
\coordinate (B) at (5, 0);
\coordinate (C) at (5, -5);
\coordinate (D) at (1, -4);
\draw (A) rectangle (C);
\MaxNodeDistance{D}{A,B,C}
\draw (A) -- (B) -- (C);
\foreach \a in {10,30,45,50,70,90}{
\draw (D) -- +(\a:\Distance);
}
\end{tikzpicture}
\end{document}


• Thank you! However, it is much code to get a length. I was wondering, that it is so difficult to calculate this length. I took your proposed veclen and create another solution. I post it in this thread. – Dirk Jun 5 '13 at 14:28

First solution, instead of 3cm use a larger length, 10cm. Your clip rectangle will cut all lines at its border.

\documentclass[margin=2mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0, 0);
\coordinate (B) at (5, 0);
\coordinate (C) at (5, -5);
\coordinate (D) at (1, -4);
\clip (A) rectangle (C);
\draw (A) -- (B) -- (C);
\foreach \a in {10,30,...,70}{
\draw (D) -- +(\a:10);
}
\end{tikzpicture}
\end{document}


Second solution: use intersections library:

\usetikzlibrary{intersections}


2- Define which paths will be intersected assigning a name to them:

\draw[name path=border] (A) -- (B) -- (C);

\path[name path=line] (D)--+(\a:10);


3- draw the angled line form its origin to intersection point:

\draw[name intersections={of=border and line}] (D) -- (intersection-1);


With this solution you don't need to use a clip path but if you need a bounding box which not considers (\a:10) points must use overlay option in:

\path[name path=line,overlay] (D)--+(\a:10);


The complete code is:

\documentclass[margin=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{tikzpicture}
\coordinate (A) at (0, 0);
\coordinate (B) at (5, 0);
\coordinate (C) at (5, -5);
\coordinate (D) at (1, -4);
%   \clip (A) rectangle (C);
\draw[name path=border] (A) -- (B) -- (C);
\foreach \a in {10,30,...,70}{
\path[name path=line,overlay] (D)--+(\a:10);
\draw[name intersections={of=border and line}] (D) -- (intersection-1);
}
\end{tikzpicture}
\end{document}


Both solutions will give you

• Your second approach needs also a manual set of the length. – Marco Daniel Jun 5 '13 at 13:53
• @MarcoDaniel: Yes, it needs. Dirk's code draws lines which don't reach the border, so I thought the problem was how to reach the border without drawing beyond it. – Ignasi Jun 5 '13 at 14:15
• I said, that it should work with different coordinates, so I do not knwo a suitable maximum length. – Dirk Jun 5 '13 at 14:26
• @Dirk: In your example you are using a fixed length. – Marco Daniel Jun 5 '13 at 14:30
• Yes, but I wrote that this does not solve my problem. I mentioned, that I can set the value to 10, but this does not solve the problem, too. – Dirk Jun 5 '13 at 15:59

I took this solution:

\documentclass[margin=2mm]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\coordinate (A) at (0cm, 0cm);
\coordinate (B) at (5cm, 0cm);
\coordinate (C) at (5cm, -5cm);
\coordinate (D) at (1cm, -4cm);

\newlength\lendiag;
\pgfmathsetlength{\lendiag}{veclen(\linewidth,\linewidth)};

\clip (A) rectangle (C);

\draw (A) -- (B) -- (C);

\foreach \a in {10,30,...,70}{
\draw (D) -- +(\a:(\lendiag););
}
\end{tikzpicture}

\end{document}


In this minimal example, I took \linewidth twice which is independend of the given points. This is not optimal, of cause. In my productive solution I use \textwidth and \textheight to determine the points and to calculate \lendiag. So the length is always long enough.