tikz:`!包 PGF 数学错误:未知函数` 在 for 循环中但在循环外有效

tikz:`!包 PGF 数学错误:未知函数` 在 for 循环中但在循环外有效

我正在使用 tikz 和 tikz-euclid 绘制一个三角形和一些矢量。

我想将三角形​​的每条边绘制为一个矢量,其长度等于边的长度,位于中点 O,并垂直于相关边。几乎与我到目前为止所绘制的一样,但矢量不是与中点相交,而是垂直。

我在这里尝试理解 tikz 语法,之前的问题中曾建议我使用 tikz-euclid。因为我要绘制多个矢量,所以我想将绘制函数放在一个循环中,如下所示:

% 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)$);
}

但这引发了一个错误:

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

但是,在循环之后重写代码:

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

产生了我想要的结果。有没有办法重写它,以便它在循环中工作\foreach?我认为循环中的行中存在一些转义序列或某些东西。但我不知道如何纠正它。有什么想法吗?

作为参考,我的代码生成了类似这样的内容,目前,如果我得到类似这样的内容但在循环中完成,我会很高兴。

在此处输入图片描述

\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}

答案1

解决问题的一种方法是少问问题。特别是将循环中的结果存储foreach到一个简单的变量中(这里,我使用了\len)。
现在,如果您想重用这些长度,您仍然可以写下您最初所做的事情,但它不会在您的循环中起作用(我目前不知道为什么,也许作为包创建者的 Alain Matthes 会知道)。

\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}

图纸

答案2

事实证明 tikz-euclid 妨碍了工作。

@Sandy G 之前回答过这个问题让我走上正确的解决方案之路。

tkz-euclid用以下代码替换

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

允许我毫不费力地将绘图命令放入循环中。

因此我的代码变成如下形式,并产生了这张图片。

在此处输入图片描述

\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}

相关内容