我有以下TikZ
代码,用于绘制网格并显示坐标。为了显示坐标,我使用了循环foreach
。
\documentclass[12pt]{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw[help lines,step=.2] (-2,-2) grid (7,4);
\draw[help lines,line width=.6pt,step=1] (-2,-2) grid (7,4);
\foreach \x in {-2,-1,0,1,2,3,4,5,6,7}
\node[anchor=north] at (\x,-2) {\x};
\foreach \y in {-2,-1,0,1,2,3,4}
\node[anchor=east] at (-2,\y) {\y};
\end{tikzpicture}
\end{document}
有没有办法简化代码,这样我有一个像这样的键show coordinates
(可能step coordinates/.initial=step
):
\draw[help lines,step=.2,show coordinates=true] (-2,-2) grid (7,4);
或者修改命令,grid
例如
\draw[help lines,step=.5] (-2,-2) gridwithcoordinates (7,4);
使用pstricks
命令非常简单\psgrid
\documentclass[12pt]{article}
\usepackage{pstricks}
\begin{document}
\begin{pspicture}(-2,-2)(7,4)
\psgrid
\end{pspicture}
\end{document}
奖金:如何设置整数坐标处的帮助线的更大线宽(见上图)?
(我不知道正确的词语 ;-))
答案1
以下是一个使用to path
s 以简单命令的形式执行任意代码的解决方案。如果前导码隐藏在包中,则调用将如下所示:
\begin{tikzpicture}
\draw (-2,-2) to[grid with coordinates] (7,4);
\end{tikzpicture}
to path
狡猾的伎俩是利用声明可以通过命令包含任意代码这一事实\pgfextra
。有了它,只需获取起始和结束坐标(编码为\tikztostart
和\tikztotarget
),然后使用原始代码(我假设您对此相当满意)作为要执行的代码即可。
加上序言,代码如下:
\documentclass{article}
%\url{}
\usepackage{tikz}
\makeatletter
\def\grd@save@target#1{%
\def\grd@target{#1}}
\def\grd@save@start#1{%
\def\grd@start{#1}}
\tikzset{
grid with coordinates/.style={
to path={%
\pgfextra{%
\edef\grd@@target{(\tikztotarget)}%
\tikz@scan@one@point\grd@save@target\grd@@target\relax
\edef\grd@@start{(\tikztostart)}%
\tikz@scan@one@point\grd@save@start\grd@@start\relax
\draw[minor help lines] (\tikztostart) grid (\tikztotarget);
\draw[major help lines] (\tikztostart) grid (\tikztotarget);
\grd@start
\pgfmathsetmacro{\grd@xa}{\the\pgf@x/1cm}
\pgfmathsetmacro{\grd@ya}{\the\pgf@y/1cm}
\grd@target
\pgfmathsetmacro{\grd@xb}{\the\pgf@x/1cm}
\pgfmathsetmacro{\grd@yb}{\the\pgf@y/1cm}
\pgfmathsetmacro{\grd@xc}{\grd@xa + \pgfkeysvalueof{/tikz/grid with coordinates/major step}}
\pgfmathsetmacro{\grd@yc}{\grd@ya + \pgfkeysvalueof{/tikz/grid with coordinates/major step}}
\foreach \x in {\grd@xa,\grd@xc,...,\grd@xb}
\node[anchor=north] at (\x,\grd@ya) {\pgfmathprintnumber{\x}};
\foreach \y in {\grd@ya,\grd@yc,...,\grd@yb}
\node[anchor=east] at (\grd@xa,\y) {\pgfmathprintnumber{\y}};
}
}
},
minor help lines/.style={
help lines,
step=\pgfkeysvalueof{/tikz/grid with coordinates/minor step}
},
major help lines/.style={
help lines,
line width=\pgfkeysvalueof{/tikz/grid with coordinates/major line width},
step=\pgfkeysvalueof{/tikz/grid with coordinates/major step}
},
grid with coordinates/.cd,
minor step/.initial=.2,
major step/.initial=1,
major line width/.initial=2pt,
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines,step=.2] (-2,-2) grid (7,4);
\draw[help lines,line width=.6pt,step=1] (-2,-2) grid (7,4);
\foreach \x in {-2,-1,0,1,2,3,4,5,6,7}
\node[anchor=north] at (\x,-2) {\x};
\foreach \y in {-2,-1,0,1,2,3,4}
\node[anchor=east] at (-2,\y) {\y};
\end{tikzpicture}
\begin{tikzpicture}
\draw (-2,-2) to[grid with coordinates] (7,4);
\end{tikzpicture}
\end{document}
(首先包含您的原始网格以供比较。顺便说一下,我在我的版本中加粗了主要线条。)
额外的位和带有@
s 的内容用于处理坐标以确定标记的开始和结束位置。假设我们从第一个坐标开始,然后根据主要步骤分隔到第二个坐标。所以我们需要处理这些坐标来提取该信息。这意味着命令的坐标可以是任何 TikZ 坐标:我们使用\tikz@scan@one@point
TikZ 本身解析坐标的方式。
需要注意的一点是使用\pgfmathprintnumber
以确保标签打印美观。
结果如下:
答案2
不完全是您要找的(没有子网格),但显示了坐标。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\def\tikz@Get@x@coor#1,#2\tikz@sentinel{%
\pgfmathparse{int(round(#1/1cm))}}
\def\tikz@Get@y@coor#1,#2\tikz@sentinel{%
\pgfmathparse{int(round(#2/1cm))}}
\tikzset{%
show grid integer coordinates/.style = {%
decoration = {%
show path construction,
moveto code = {%
\expandafter\tikz@Get@x@coor\tikzinputsegmentfirst\tikz@sentinel
\edef\tikz@tempa{\pgfmathresult}%
\expandafter\tikz@Get@x@coor\tikzinputsegmentlast\tikz@sentinel
\edef\tikz@tempb{\pgfmathresult}%
\pgfmathparse{equal(\tikz@tempa,\tikz@tempb)}%
\ifnum\pgfmathresult=1\relax
\node[anchor=north] at (\tikzinputsegmentfirst) {%
\tikz@tempa};
\else
\node[anchor=east] at (\tikzinputsegmentfirst) {%
\expandafter\tikz@Get@y@coor\tikzinputsegmentfirst\tikz@sentinel
\pgfmathresult};
\fi}},
postaction = decorate}}
\begin{document}
\begin{tikzpicture}
\draw[show grid integer coordinates] (-2,2) grid (7,4);
\end{tikzpicture}
\end{document}
可以用同样的想法添加子网格,但是这太过分了...我不知道如何访问右上角的 x 坐标:在 moveto 代码中\tikz@lastx
设置为。0.0pt
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,calc}
\makeatletter
\def\tikz@Get@x@coor#1,#2\tikz@sentinel{%
\pgfmathparse{int(round(#1/1cm))}}
\def\tikz@Get@y@coor#1,#2\tikz@sentinel{%
\pgfmathparse{int(round(#2/1cm))}}
\tikzset{%
show grid integer coordinates/.style = {%
preaction = {%
decoration = {%
show path construction,
moveto code = {%
\expandafter\tikz@Get@x@coor\tikzinputsegmentfirst\tikz@sentinel
\edef\tikz@tempa{\pgfmathresult}%
\expandafter\tikz@Get@x@coor\tikzinputsegmentlast\tikz@sentinel
\edef\tikz@tempb{\pgfmathresult}%
\pgfmathparse{equal(\tikz@tempa,\tikz@tempb)}%
\ifnum\pgfmathresult=1\relax
\node[anchor=north] at (\tikzinputsegmentfirst) {%
\tikz@tempa};
\draw[help lines,step=.1] (\tikzinputsegmentfirst) grid
($(\tikzinputsegmentlast)+(1,0)$);
\else
\node[anchor=east] at (\tikzinputsegmentfirst) {%
\expandafter\tikz@Get@y@coor\tikzinputsegmentfirst\tikz@sentinel\pgfmathresult};
\fi}},
decorate}}}
\begin{document}
\begin{tikzpicture}
\draw[show grid integer coordinates] (-2,2) grid (7,4);
\end{tikzpicture}
\end{document}
答案3
很抱歉,没有简单的解决方案。首先,我尝试使用,to path
但它不允许您更改线条样式:-(接下来,我尝试实现专用命令。这次的主要问题是为了迭代坐标标签,标签应该是整数,这通常不是真的。下面的方法应该有效,但它需要每个坐标由两个整数组成;不允许有理数和标签。应该可以实现一个采用更通用参数的宏,但这会花费太长时间。
\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\newif\ifmygrid@coordinates
\tikzset{/mygrid/step line/.style={line width=0.80pt,draw=gray!80},
/mygrid/steplet line/.style={line width=0.25pt,draw=gray!80}}
\pgfkeys{/mygrid/.cd,
step/.store in=\mygrid@step,
steplet/.store in=\mygrid@steplet,
coordinates/.is if=mygrid@coordinates}
\def\mygrid@def@coordinates(#1,#2)(#3,#4){%
\def\mygrid@xlo{#1}%
\def\mygrid@xhi{#3}%
\def\mygrid@ylo{#2}%
\def\mygrid@yhi{#4}%
}
\newcommand\DrawGrid[3][]{%
\pgfkeys{/mygrid/.cd,coordinates=true,step=1,steplet=0.2,#1}%
\draw[/mygrid/steplet line] #2 grid[step=\mygrid@steplet] #3;
\draw[/mygrid/step line] #2 grid[step=\mygrid@step] #3;
\mygrid@def@coordinates#2#3%
\ifmygrid@coordinates%
\draw[/mygrid/step line]
\foreach \xpos in {\mygrid@xlo,...,\mygrid@xhi} {%
(\xpos,\mygrid@ylo) -- ++(0,-3pt)
node[anchor=north] {$\xpos$}
}
\foreach \ypos in {\mygrid@ylo,...,\mygrid@yhi} {%
(\mygrid@xlo,\ypos) -- ++(-3pt,0)
node[anchor=east] {$\ypos$}
};
\fi%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\DrawGrid{(-2,-1)}{(3,2)}
%\DrawGrid[coordinates=false]{(-2,-1)}{(3,2)}
\end{tikzpicture}
\end{document}