É possível nomear parâmetros de macro (`\newcommand`) e fazer contas com eles?

É possível nomear parâmetros de macro (`\newcommand`) e fazer contas com eles?

Sou novo na criação de comandos em LaTeX e gostaria de fazer algo como adicionar um nome mais útil dentro do meu comando, enquanto faço cálculos com ele; ao mesmo tempo que faz algumas contas com esse parâmetro. Aqui está um exemplo:

\documentclass{article}

\usepackage{tikz}

\newcommand{\gogrid}[1][1]{
  % Here are some of my attempts:

  % \def\size{#1 / 19}
  \newlength{\size}
  \setlength{\size}{#1 / 19}
  % Maybe I need to specify the type of the `#1` parameter?

  \draw[step=#1 / 19] (-#1, -#1) grid (#1,#1);
  \draw[line width=1] (-#1, #1) -- (#1 + 0.015, #1); % chktex 8
  \draw[line width=1] (#1, -#1) -- (#1, #1); % chktex 8
}

\begin{document}
  \begin{figure}[h]
    \begin{center}
      \begin{tikzpicture}
        \gogrid
        % \draw(-5,-5) grid (5,5);
        \filldraw[black](0,0)circle[radius=3pt];
        \filldraw[black](1,1)circle[radius=3pt];
      \end{tikzpicture}
      \caption{\label{my_grid}A grid with two points!}
    \end{center}
  \end{figure}
\end{document}

Isso é possível em LaTeX? Eu uso muito esse tipo de coisa em linguagens de programação regulares para tornar as coisas mais legíveis. (Além disso, se alguém tiver uma referência de livro ou site com esse tipo de coisa, eu realmente apreciaria.)

Responder1

Tudo estará funcionando no seu exemplo, se você puder definir uma unidade adequada para o argumento #1no \setlengthcomando, enquanto usa a sintaxe adequada para cálculo de dimensão dentro do TikZ também. Você poderia omitir as unidades para o desenho TikZ, mas não para o cálculo da dimensão. Então você deve usar \setlength{\size}{\dimexpr#1cm/19\relax}.

No TikZ, se a unidade das coordenadas for omitida, então cmserão assumidas. Para largura da linha, ptserá usado.

Conforme mencionado nos comentários, \newlength{\size}deve ser colocado fora da definição do comando, porque você não precisa redefinir o mesmo novo comprimento todas as vezes.

Aqui estão dois exemplos usando seu código para gerar a grade. Imprimi o valor de \sizecomo um nó abaixo do ponto central e defini o raio do ponto central igual ao \sizecomprimento, apenas para mostrar que os cálculos de dimensão realmente funcionaram. Os pontos centrais ocupam exatamente 4 blocos.

\documentclass{article}

\usepackage{tikz}

\newlength{\size}
\newcommand{\gogrid}[1][1]{
  \setlength{\size}{\dimexpr#1cm/19\relax}

  \draw[step=\size] (-#1, -#1) grid (#1,#1);
  \draw[red,line width=1] (-#1, #1) -- (\dimexpr#1cm+1cm , #1); 
  \draw[blue,line width=1] (#1, -#1) -- (#1, #1);
}

\begin{document}
  \begin{figure}[ht]
    \begin{center}
      \begin{tikzpicture}
        \gogrid
        \filldraw (0,0) circle [radius=1.49751pt] node[below] {\the\size};
        \filldraw (1,1) circle[radius=1.49751pt];
      \end{tikzpicture}
      \caption{A grid with two points!}\label{my_grid1}
    \end{center}
  \end{figure}

  \begin{figure}[ht]
    \begin{center}
      \begin{tikzpicture}
        \gogrid[5]
        \filldraw (0,0) circle [radius=7.48756pt] node[below=0.5cm] {\the\size};
        \filldraw (5,5) circle[radius=3pt];
      \end{tikzpicture}
      \caption{Another grid with two points!}\label{my_grid2}
    \end{center}
  \end{figure}
\end{document}

Saída:

tamanho padrão = 1 tamanho = 5

Responder2

Se você estiver fazendo isso dentro de tikzpictures, basta deixar pgfmathos cálculos. Simplesmente excluir as linhas \newlength...e \setlength...funciona.

\newcommand{\gogrid}[1][1]{%
  \draw[step=#1 / 19] (-#1, -#1) grid (#1,#1);
  \draw[line width=1] (-#1, #1) -- (#1 + 0.015, #1); % chktex 8
  \draw[line width=1] (#1, -#1) -- (#1, #1); % chktex 8
}

permite \gogrid[<number or length>]dentro de tikzpictures.

\begin{tikzpicture}
  \gogrid[10mm]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\begin{tikzpicture}
  \gogrid[5]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}

No entanto, para este uso específico, você pode usar griddiretamente.

\begin{tikzpicture}
  \draw [step=2/19]  (-2,-2) grid (2,2);
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}

três grades

Observe que se você não especificar unidades, o PGF usará a unidade atual na maioria dos casos. Por padrão, é 1 cm em cada eixo, mas o valor é personalizável e pode ser definido independentemente para horizontal e vertical, se necessário.

Código completo:

\documentclass{standalone}

\usepackage{tikz}
\newcommand{\gogrid}[1][1]{%
  \draw[step=#1 / 19] (-#1, -#1) grid (#1,#1);
  \draw[line width=1] (-#1, #1) -- (#1 + 0.015, #1); % chktex 8
  \draw[line width=1] (#1, -#1) -- (#1, #1); % chktex 8
}

\begin{document}
\begin{tikzpicture}
  \gogrid[10mm]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\begin{tikzpicture}
  \gogrid[5]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\begin{tikzpicture}
  \draw [step=2/19]  (-2,-2) grid (2,2);
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\end{document}

EDITAR

Se você quiser usar uma macro em vez de um parâmetro nos cálculos para maior clareza, eu usaria pgfkeysse você estivesse fazendo isso em um arquivo tikzpicture. Existem várias maneiras de configurar isso, mas, se você quiser apenas especificar o tamanho (e não quiser ajustar a grade com outras opções), eu tentaria algo como

\documentclass{standalone}
\usepackage{tikz}
\tikzset{%
  go grid/.code={%
    \tikzset{%
      go grid/.cd,
      size=#1,
    }%
    \draw [step=\gogridsize/19] (-\gogridsize, -\gogridsize) grid (\gogridsize,\gogridsize);
    \draw[line width=1] (-\gogridsize, \gogridsize) -- (\gogridsize + 0.015, \gogridsize); % chktex 8
    \draw[line width=1] (\gogridsize, -\gogridsize) -- (\gogridsize, \gogridsize); % chktex 8
  },
  go grid/.default=10mm,
  go grid/.cd,
  size/.store in=\gogridsize,
  size/.initial=1cm,
}

\begin{document}
\begin{tikzpicture}[go grid]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\begin{tikzpicture}[go grid=5]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\begin{tikzpicture}[go grid=20mm]
  \filldraw[black](0,0)circle[radius=3pt];
  \filldraw[black](1,1)circle[radius=3pt];
\end{tikzpicture}
\end{document}

Se quiser várias grades por imagem, você pode usar um picou, como fez inicialmente, apenas definir um comando.

\newcommand{\gogrid}[1][1]{%
  \tikzset{go grid/size=#1,go grid}%
}

Se você quiser especificar outros aspectos das grades, existem novamente abordagens diferentes. Eu provavelmente tentaria algo como

\documentclass{standalone}
\usepackage{tikz}
\tikzset{% ateb: https://tex.stackexchange.com/a/708415/ addaswyd o gwestiwn: https://tex.stackexchange.com/q/708410/
  go grid/.search also={/tikz,/pgf},
  go grid/.code={%
    \tikzset{%
      go grid/.cd,
      #1,
    }%
    \begin{scope}[draw=\gogridcolour]
      \draw [step=\gogridsize/19] (-\gogridsize, -\gogridsize) grid (\gogridsize,\gogridsize);
      \draw[line width=1] (-\gogridsize, \gogridsize) -- (\gogridsize + 0.015, \gogridsize); % chktex 8
      \draw[line width=1] (\gogridsize, -\gogridsize) -- (\gogridsize, \gogridsize); % chktex 8
    \end{scope}
    \edef\tempa{}\edef\tempb{\gogridstonesat}%
    \ifx\tempa\tempb
    \else
      \foreach \i in \gogridstonesat \filldraw[\gogridstones]\i circle [radius=\gogridstonesize];
    \fi
  },
  go grid/.default={size=10mm},
  go grid/.cd,
  grid/.store in=\gogridcolour,
  grid=black,
  size/.store in=\gogridsize,
  size=1cm,
  stone size/.store in=\gogridstonesize,
  stone size=3pt,
  stones/.store in=\gogridstones,
  stones=black,
  stones at/.store in=\gogridstonesat,
  stones at={},
}
\NewDocumentCommand \gogrid { O{} }
{%
  \tikz[go grid={#1}]{}%
}

\begin{document}
\begin{tikzpicture}[go grid={grid=blue,stones at={(0,0),(1,1)},stones=red}]
\end{tikzpicture}
\begin{tikzpicture}[go grid={size=5,stones at={(0,0),(1,1)}}]
\end{tikzpicture}
\begin{tikzpicture}[go grid={size=20mm,grid=green,stones at={(0,0),(1,1)},stone size=4pt}]
  \node [above] at (current bounding box.north) {Green Go Grid};
\end{tikzpicture}
\gogrid
\gogrid[size=2.5cm,grid=orange,stones at={(0,1),(1,0),(-1,0),(0,-1)},stone size=2.5pt,stones=blue]
\end{document}

Várias grades go personalizadas

informação relacionada