在另一个关于访问逻辑坐标的问题中
我使用了这些函数,直到我得到一个缩放的 tikzpicture,然后它就关闭了。我现在为缩放添加了一个因子,但我正在寻找一种使其通用的方法。这意味着 xcoord/ycoord 将通过 tikz/pgf 变量考虑图片的缩放。
\makeatletter
\newcommand\xcoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@x/\pgf@xx}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\newcommand\ycoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@y/\pgf@yy}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\makeatother
有这方面的建议吗?
MWE 是:
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgffor}
\makeatletter
\newcommand\xcoorda[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@x/\pgf@xx}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\makeatletter
\newcommand\xcoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@x/\pgf@xx/.17}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\newcommand\ycoorda[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@y/\pgf@yy}%
\pgfmathprintnumber{\pgfmathresult}%
}}
\makeatother
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}[domain=-0.01:0.55,xscale=17,yscale=0.01]
% the scaling is also in xcoord
\draw[-stealth,name path=xline] (0,0) -- (0.55,0);
\draw[stealth-stealth,name path=yline] (0,-220) -- (0,220);
\draw[color=blue,name path=func] (0,200) parabola bend (.25,-50) (.50,200);
\path[name intersections={of=func and xline,by={i1,i2}}];
\node[above=15pt] (i1label) at(i1) {\xcoord{i1}\%};
\draw[-stealth,green] (i1label.south) -- (i1);
\node[below=20pt,text width=2cm,align=center,draw,fill=red!25] (i1label_a)
at(i1) {\xcoorda{i1}\%\\ sans scaling \\ wrong!};
\draw[-stealth,red] (i1label_a.north) -- (i1);
\node[above=15pt] (i2label) at(i2) {\xcoord{i2}\%};
\draw[-stealth,green] (i2label.south) -- (i2);
\node[below=20pt,text width=2cm,draw,align=center,fill=red!25] (i2label_a)
at(i2) {\xcoorda{i2}\%\\ sans scaling \\ wrong!};
\draw[-stealth,red] (i2label_a.north) -- (i2);
\foreach \t in {10,20,...,50} {
\pgfmathparse{\t/100}\edef\v{\pgfmathresult}
\draw[thin] (\v,10) -- (\v,-10) node[below] {\t\%};
}
\foreach \t in {-200,-100,...,200} {
\draw[thin] (.010,\t) -- (-0.01,\t) node[left] {\small\t};
}
\end{tikzpicture}
\end{document}
我在 MWE 中使用了抛物线,并在两种情况下标记了缩放和未缩放的 xcoord。
答案1
问题出现是因为\xcoorda
在节点内部调用了 ,这会重置变换矩阵,因此\pgf@xx
无法正确缩放。要避免这种情况,您可以做的是在 using 开始时将变换矩阵保存到宏中tikzpicture
,\pgfgettransform{<macro>}
然后在\xcoorda
宏 using中设置它\pgfsettransform{<macro>}
。为了在表达式中使用结果坐标\pgfmathparse
,我建议将宏转换为pgfmath
函数。我已在下面的代码中包含了这种方法。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}
\makeatletter
\newcommand\xcoorda[2][center]{{%
%
% Set the transformation matrix that was saved at the beginning of the tikzpicture
%
\pgfsettransform{\transform}%
\pgfpointanchor{#2}{#1}%
\pgfmathparse{\pgf@x/\pgf@xx}%
\pgfmathresult%
}}
\pgfmathdeclarefunction{xcoord}{1}{
\pgfsettransform{\transform}%
\pgfpointanchor{#1}{center}%
\pgfmathparse{\pgf@x/\pgf@xx}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[domain=-0.01:0.55,xscale=17,yscale=0.01]
% Save the transformation matrix
\pgfgettransform{\transform}
\draw[-stealth,name path=xline] (0,0) -- (0.55,0);
\draw[stealth-stealth,name path=yline] (0,-220) -- (0,220);
\draw[color=blue,name path=func] (0,200) parabola bend (.25,-50) (.50,200);
\path[name intersections={of=func and xline,by={i1,i2}}];
\node[below=20pt,text width=2cm,align=center,draw,fill=green!25] (i1label_a)
at(i1) {\xcoorda{i1}\\correct};
\draw[-stealth,red] (i1label_a.north) -- (i1);
\node[below=20pt,text width=2cm,draw,align=center,fill=green!25] (i2label_a)
at(i2) {\pgfmathparse{xcoord("i2")*100}\pgfmathprintnumber{\pgfmathresult}\,\%\\ correct};
\draw[-stealth,red] (i2label_a.north) -- (i2);
\foreach \t in {10,20,...,50} {
\pgfmathsetmacro\v{\t/100}
\draw[thin] (\v,10) -- (\v,-10) node[below] {\t\%};
}
\foreach \t in {-200,-100,...,200} {
\draw[thin] (.010,\t) -- (-0.01,\t) node[left] {\small\t};
}
\end{tikzpicture}
\end{document}
如果您使用 PGFplots,则可以避免手动保存和恢复坐标转换,因为在这种情况下,您可以使用\pgfplotsunitxlength
,它保存 x 单位向量的长度乘以 1000,以及\pgfplotspointaxisorigin
,它保存当前轴的点 (0,0):
\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{intersections}
\newcommand\xcoord[2][center]{{%
\pgfpointanchor{#2}{#1}%
\pgfgetlastxy{\ix}{\iy}%
\pgfplotspointaxisorigin%
\pgfgetlastxy{\ox}{\oy}
\pgfmathparse{(\ix-\ox)/\pgfplotsunitxlength/1000}
\pgfmathprintnumber{\pgfmathresult}}
}
\begin{document}
\vspace{1cm}
\begin{tikzpicture}
\begin{axis}[
domain=0:0.5,
samples=100,
no markers,
axis lines=middle,
enlarge x limits=upper,
enlarge y limits=true,
xticklabel=\pgfmathparse{\tick*100}\pgfmathprintnumber{\pgfmathresult}\,\%,
x axis line style={{name path global=xaxis}}
]
\addplot +[name path global=plot] {4000*(x-0.25)^2-50};
\pgfplotsextra{
\fill [name intersections={of=xaxis and plot, name=i, total=\t}]
[red, every node/.style={black}]
(i-1) circle (2pt) node [pin={\xcoord{i-1}}] {}
(i-2) circle (2pt) node [pin={\xcoord{i-2}}] {};
}
\end{axis}
\end{tikzpicture}
\end{document}