4

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.

5

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}

enter image description here

  • 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
4

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:

1- Load 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

enter image description here

  • 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
1

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.

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.