如何在 TikZ 中自动按网格显示坐标?

如何在 TikZ 中自动按网格显示坐标?

我有以下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);

enter image description here

使用pstricks命令非常简单\psgrid

\documentclass[12pt]{article}
\usepackage{pstricks}

\begin{document}
\begin{pspicture}(-2,-2)(7,4)
\psgrid
\end{pspicture}
\end{document}

奖金:如何设置整数坐标处的帮助线的更大线宽(见上图)?

(我不知道正确的词语 ;-))

答案1

以下是一个使用to paths 以简单命令的形式执行任意代码的解决方案。如果前导码隐藏在包中,则调用将如下所示:

\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@pointTikZ 本身解析坐标的方式。

需要注意的一点是使用\pgfmathprintnumber以确保标签打印美观。

结果如下:

TikZ grid with labels

答案2

不完全是您要找的(没有子网格),但显示了坐标。

grid with coordinates

\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

subgrid

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

相关内容