0

I am working on drawing a triangle and some vectors using tikz and tikz-euclid.

I want to draw each edge of my triangle as a vector, with length equal to the length of the edge, located at the midpoint, O, and perpendicular to the relevant edge. Almost like what I have sketched so far, but instead of intersecting the midpoints, the vectors should be perpendicular.

I'm trying to get my head around tikz syntax here, and had tikz-euclid suggested to me from a previous question. Because I am drawing more than one vector I would like to put the draw functions in a loop, like so:

% 1. Coordinates of the line segment midpoints, E,F,G
% 2. get lengths of vectors A, B, C (as, dA, dB, dC)
% 3. draw the vectors from O passing through relevant midpoint
\foreach \mid/\tip/\tail/\vector in {E/P/Q/A, F/Q/R/B, G/R/P/C}{
    \coordinate (\mid) at ($(\tip)!0.5!(\tail)$);
% Calculate length of segments and label as dA, dB, dC 
\tkzCalcLength(\tip,\tail)\tkzGetLength{d\vector}

%THIS throws an error:
%> ! Package PGF Math Error: Unknown function `dApt' (in 'dApt').
\draw[->] (O)--++ ($(O)!d\vector pt!(\mid)-(O)$);

}

But this has thrown an error:

! Package PGF Math Error: Unknown function 'dApt' (in 'dApt')

However, re-writting the code just after the loop:

\draw[->] (O)--++ ($(O)!\dA pt!(E)-(O)$);
\draw[->] (O)--++ ($(O)!\dB pt!(F)-(O)$);
\draw[->] (O)--++ ($(O)!\dC pt!(G)-(O)$);

Produces what I want. Is there a way to re-write this so that it works within the \foreach loop? I figure there is some escape sequencing or something messing with the line in the loop. But I can't figure out how to get it right. Any ideas?

For reference the code I have generates something that looks like this, and for the moment if I get something that looks like this out but done in a loop I will be happy.

enter image description here

\documentclass[border=20pt]{standalone}

\usepackage{tikz} \usetikzlibrary{intersections, calc,through,backgrounds} \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) ;


    % 1. Coordinates of the line segment midpoints, E,F,G
    % 2. get lengths of vectors A, B, C (as, dA, dB, dC)
    % 3. draw the vectors from O passing through relevant midpoint
    \foreach \mid/\tip/\tail/\vector in {E/P/Q/A, F/Q/R/B, G/R/P/C}{
        \coordinate (\mid) at ($(\tip)!0.5!(\tail)$);

       % Calculate length of segments and label as dA, dB, dC 
        \tkzCalcLength(\tip,\tail)\tkzGetLength{d\vector}

        %THIS throws an error:
        %> ! Package PGF Math Error: Unknown function `dApt' (in 'dApt').
        %\draw[->] (O)--++ ($(O)!d\vector pt!(\mid)-(O)$);
    }

    % This works
    % Draw the vectors A,B,C from O, passing through E,F,G respectivley
    \draw[->] (O)--++ ($(O)!\dA pt!(E)-(O)$);
    \draw[->] (O)--++ ($(O)!\dB pt!(F)-(O)$);
    \draw[->] (O)--++ ($(O)!\dC pt!(G)-(O)$);


    \draw [thin] (P) -- node[midway,sloped] {$||$}(Q) --node[midway,sloped] {$||$} (R) --node[midway,sloped] {$||$} 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$};

    % midpoints
    \begin{scope}[black!40]
    \node at (E) [below left=.5em]{$E$};
    \node at (F) [below=.5em]{$F$};
    \node at (G) [below right=.5em]{$G$};
    \end{scope}


\end{tikzpicture}

\end{document}

2 Answers2

2

Turns out tikz-euclid was getting in the way.

This answer by @Sandy G earlier put me on the path to the right solution.

replacing the tkz-euclid code with

\draw[->, blue] let 
                \p1 = ($(\tip)-(\tail)$)
            in
                (O)--++($(O)!sqrt(\x1*\x1+\y1*\y1)!(\mid)-(O)$);

allowed me to put the draw command in a loop without too much of a hassle.

Thus my code became the following, which produced this picture.

enter image description here

\documentclass[border=20pt]{standalone}

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

\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) ;


    % 1. Coordinates of the line segment midpoints, E,F,G
    % 2. draw the vectors from O passing through relevant midpoint
    \foreach \mid/\tip/\tail/\vector in {E/P/Q/A, F/Q/R/B, G/R/P/C}{
        \coordinate (\mid) at ($(\tip)!0.5!(\tail)$);

        \draw[->, blue] let 
            \p1 = ($(\tip)-(\tail)$)
        in
            (O)--++($(O)!sqrt(\x1*\x1+\y1*\y1)!(\mid)-(O)$);
    }

    % Draw triangle, and midpoint markers
    \draw [thin] (P) -- node[midway,sloped] {$||$}(Q) --node[midway,sloped] {$||$} (R) --node[midway,sloped] {$||$} cycle;

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

    % Labels: midpoints
    \begin{scope}[black!40]
    \node at (E) [below left=.5em]{$E$};
    \node at (F) [below=.5em]{$F$};
    \node at (G) [below right=.5em]{$G$};
    \end{scope}


\end{tikzpicture}

\end{document}

  • While this does solve my immediate problem, i think I would like to use tkz-euclid in the future, so any ideas on how to rewrite the offending line of code would still be appreciated – Andrew Micallef Feb 13 '21 at 02:46
1

One way of solving your issue is to ask less. Especially store the result in your foreach loop into a simple variable (here, I used \len).
Now, if you want to reuse these length, you can still write what you did in the first place, but it won't work into your loop (and I currently don't know why, maybe Alain Matthes would know, as the package creator).

\documentclass[border=20pt]{standalone}

\usepackage{tikz} \usetikzlibrary{intersections, calc,through,backgrounds} \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) ;


    % 1. Coordinates of the line segment midpoints, E,F,G
    % 2. get lengths of vectors A, B, C (as, dA, dB, dC)
    % 3. draw the vectors from O passing through relevant midpoint
    \foreach [count=\i] \mid/\tip/\tail/\v in {E/P/Q/A, F/Q/R/B, G/R/P/C}{
        \coordinate (\mid) at ($(\tip)!0.5!(\tail)$);

       % Calculate length of segments and label as dA, dB, dC (NOT)

        \tkzCalcLength(\tip,\tail)\tkzGetLength{len}    % PROBLEM SOLVED
        \draw[->] (O)--++ ($(O)!\len pt!(\mid)-(O)$);   % PROBLEM SOLVED
    }        

    \draw [thin] (P) -- node[midway,sloped] {$||$}(Q) --node[midway,sloped] {$||$} (R) --node[midway,sloped] {$||$} 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$};

    % midpoints
    \begin{scope}[black!40]
    \node at (E) [below left=.5em]{$E$};
    \node at (F) [below=.5em]{$F$};
    \node at (G) [below right=.5em]{$G$};
    \end{scope}


\end{tikzpicture}

\end{document}

the drawings

SebGlav
  • 19,186