2

I have some tikz code that draws a triangle with labelled verticies.

I would like to draw a line that starts at the origin, intersecting the point labelled P, and has a length equal to the edge labelled A.

I figure that the calc library is what I want for this, but I'm having trouble working out how to feed it the length of A...

Here is my code so far, with my best guess at what I think the edge I want to draw command will look like:

\documentclass{standalone}

\usepackage{tikz} \usetikzlibrary{intersections, calc, through, backgrounds}

\begin{document}

\begin{tikzpicture}[scale=3]

% layout some coordinates for a triangle \coordinate (P) at ($(0,0) + (rand,rand)$); \coordinate (Q) at ($(2,-2) + .5(rand, rand)$); \coordinate (R) at ($(-2, -2) + .5(rand, rand)$); %convienience for finding the centre \coordinate (PQR) at ($(P)+(Q)+(R)$); \coordinate (O) at ($1/3*(PQR)$);

%draw triangle \draw[name path=A] (P) -- (Q); \draw[name path=B] (Q) -- (R); \draw[name path=C] (R) -- (P);

%labels \node at (O) {$O$}; \node at (P) [above=2pt]{$P$}; \node at (Q) [right=2pt]{$Q$}; \node at (R) [left=2pt]{$R$};

\node at ($(P)!.5!(Q)$) [above right=1em]{$\mathbf{A}$};

%draw a path of length (A) from (O), passing through (P) %\draw[name path=U] (O) -- ($(O)! !(B)$)

\end{tikzpicture} \end{document}

Which gives me this output enter image description here

  • some clarity is desired with a hand drawn sketch of the output – js bibra Feb 12 '21 at 14:22
  • 1
    With tkz-euclide, you can get the length of a segment with \tkzCalcLength macro. And not related, but finding the centroid is shorter with \coordinate (O) at (barycentric cs:P=1,Q=1,R=1) ;. – SebGlav Feb 12 '21 at 16:47
  • 1
    Thanks SebGlav, I didn't know about that centroid command, I figured there might be a better way. Also my desired output is the output yeilded by sebglavs answer – Andrew Micallef Feb 12 '21 at 22:24

2 Answers2

3

You can calculate the length of the "vector" (\x,\y) using sqrt(\x1*\x1+\y1*\y1). Then use the construction

($(A)!<len>!(B)-(A)$)

to create a vector from (A) in the direction of (B) – (A) with length <len>:

enter image description here

Here, the blue line has endpoints (A) = (1,0) and (B) = (3,1). The red line is drawn from (C) = (1,1) through (D) = (2,2) with the length of the line from (A) to (B) using the code

\draw[red,thick] let\p1=($(B)-(A)$) in (C)--++($(C)!sqrt(\x1*\x1+\y1*\y1)!(D)-(C)$);

The let command assigns to \p1 the "vector" from (A) to (B), which automatically assigns its x and y components to \x1 and \y1.

If you wish, you could define a command \thru that takes 5 arguments, one optional:

\newcommand{\thru}[5][]{\draw[#1] let\p1=($#5-#4$) in #2--++($#2!sqrt(\x1*\x1+\y1*\y1)!#3-#2$);}

The optional argument would be any tikz attributes you want. The first required argument is your starting point, the second is the through point, the third and fourth are the endpoints of the segment whose length you want.

So \thru[green,thick]{(2,1)}{(3,2)}{(A)}{(B)} would draw the thick green line from (2,1) through (3,2) having the length of segment (A)--(B).

\documentclass{article}

\usepackage{tikz} \usetikzlibrary{calc}

\newcommand{\thru}[5][]{\draw[#1] let\p1=($#5-#4$) in #2--++($#2!sqrt(\x1\x1+\y1\y1)!#3-#2$);}

\begin{document}

\begin{tikzpicture} \draw[help lines] (0,0) grid (4,3); \coordinate(A) at (1,0); \coordinate(B) at (3,1); \coordinate(C) at (1,1); \coordinate(D) at (2,2); \draw[blue,thick] (A)--(B);

\draw[red,thick] let\p1=($(B)-(A)$) in (C)--++($(C)!sqrt(\x1\x1+\y1\y1)!(D)-(C)$); \thru[green,thick]{(2,1)}{(3,2)}{(A)}{(B)}

\end{tikzpicture}

\end{document}

Sandy G
  • 42,558
  • It's known that veclen is sometimes very sloppy. That's why I prefer using tkz-euclide to get a segment length. – SebGlav Feb 12 '21 at 17:49
  • @SebGlav, in what sense is veclen sloppy? I've never experienced any issues using it in this fashion (with a vector quantity for input). Can you point me to an example? – Sandy G Feb 12 '21 at 18:37
  • https://tex.stackexchange.com/questions/521541/how-to-get-the-length-of-a-segment-in-tikz-in-a-macro (actually, I'm used to tkz-euclide and just dropped any other possibilities which coexist) – SebGlav Feb 12 '21 at 19:15
  • 1
    @SebGlav, thanks. That's somewhat bizarre. Is there a reason not to use sqrt(\x1^2+\y1^2)? That doesn't seem to have the same issue. I always assumed veclen was just a shortcut for the sqrt calculation. But apparently not. I edited my response. – Sandy G Feb 12 '21 at 19:36
  • 1
    Actually, sqrt(\x1*\x1+\y1*\y1) is better. – Sandy G Feb 12 '21 at 22:02
2

Using tkz-euclide, you may use this:

\documentclass[tikz,border=10pt]{standalone}

\usepackage{tkz-euclide}

\begin{document}

\begin{tikzpicture}[scale=3]

    % Coordinates for a triangle
    \coordinate (P) at ($(0,0) + (rand,rand)$);
    \coordinate (Q) at ($(2,-2) + .5*(rand, rand)$);
    \coordinate (R) at ($(-2, -2) + .5*(rand, rand)$);
    \coordinate (O) at (barycentric cs:P=1,Q=1,R=1) ;

    % Draw triangle
    \draw (P) -- (Q) node[midway,above,sloped] {dist $=A$}  -- (R) -- cycle;

    \tkzDrawPoints(P,Q,R,O)

    % Labels
    \node at (O) [left=2pt]{$O$};
    \node at (P) [above right]{$P$};
    \node at (Q) [right=2pt]{$Q$};
    \node at (R) [left=2pt]{$R$};

    % Calculate length of segment PQ and label as dPQ
    \tkzCalcLength(P,Q)\tkzGetLength{dPQ}

    % Create some point on a circle centred on O and with radius = PQ length
    \tkzDefPointOnCircle[angle=90,center=O,radius=\dPQ pt]
    \tkzGetPoint{I}

    % Find intersection between line OP and previous circle
    % Two points, but only one is useful
    \tkzInterLC(O,P)(O,I) \tkzGetPoints{D}{E}

    % Draw the segment from O, passing through P, the length of PQ
    \draw[dashed,blue] (O) -- (E) node[pos=0.7,left] {dist$=A$};

    \tkzDrawPoints(E)
    \tkzLabelPoints[left](E)

\end{tikzpicture}

\end{document}

centroid and calc length

EDIT
Taking advantage of this other clever option (apart from veclen which I definitely would not use), here comes another shorter version, using tikz-euclide to compute the segment length and a simpler implementation of the drawn segment.

\documentclass[tikz,border=10pt]{standalone}

\usepackage{tkz-euclide}

\begin{document}

\begin{tikzpicture}[scale=3]

    % Coordinates for a triangle
    \coordinate (P) at ($(0,0) + (rand,rand)$);
    \coordinate (Q) at ($(2,-2) + .5*(rand, rand)$);
    \coordinate (R) at ($(-2, -2) + .5*(rand, rand)$);
    \coordinate (O) at (barycentric cs:P=1,Q=1,R=1) ;

    % Draw triangle
    \draw (P) -- (Q) node[midway,above,sloped] {dist $=A$}  -- (R) -- cycle;

    \tkzDrawPoints(P,Q,R,O)

    % Labels
    \node at (O) [left=2pt]{$O$};
    \node at (P) [above right]{$P$};
    \node at (Q) [right=2pt]{$Q$};
    \node at (R) [left=2pt]{$R$};

    % Calculate length of segment PQ
    \tkzCalcLength(P,Q)\tkzGetLength{dPQ}

    % Draw the segment from O, passing through P, the length of PQ
    \draw[orange,thick,dashed] (O)--++ ($(O)!\dPQ pt!(P)-(O)$) coordinate[at end] (E);

    \tkzDrawPoints(E)
    \tkzLabelPoints[left](E)


\end{tikzpicture}

\end{document}

version 2

SebGlav
  • 19,186
  • Just one quick thing, why would you definitly not use veclen? Care to add a citation or side sentence on that? Otherwise thanks for all the help, this is exactly what I needed – Andrew Micallef Feb 12 '21 at 22:33
  • 1
    @AndrewMicallef, as @SebGlav points out in the comments of my response (below), veclen is slightly imprecise. It can be off by a small fraction of a percent. Specifically, in a 50pt line segment, as the hypotenuse of a 30pt, 40pt, 50pt right triangle, veclen measures 49.99512pt. For most uses, this is not noticeable, so I wouldn't say definitely not to use it, but @SebGlav's solution is indeed more precise. Another way is to use sqrt(\x1*\x1+\y1*\y1) to measure the length. – Sandy G Feb 13 '21 at 00:02
  • Ah, I see, I'm still new to tikz, so had no idea how to capture the coordinates... but I think you clarified that in your answer, by using the let command so thankyou for that too – Andrew Micallef Feb 13 '21 at 00:06