![tikz:`!包 PGF 数学错误:未知函数` 在 for 循环中但在循环外有效](https://linux22.com/image/428811/tikz%EF%BC%9A%60%EF%BC%81%E5%8C%85%20PGF%20%E6%95%B0%E5%AD%A6%E9%94%99%E8%AF%AF%EF%BC%9A%E6%9C%AA%E7%9F%A5%E5%87%BD%E6%95%B0%60%20%E5%9C%A8%20for%20%E5%BE%AA%E7%8E%AF%E4%B8%AD%E4%BD%86%E5%9C%A8%E5%BE%AA%E7%8E%AF%E5%A4%96%E6%9C%89%E6%95%88.png)
我正在使用 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}