「foreach 変数」を使用した calc ライブラリの理解不能な動作

「foreach 変数」を使用した calc ライブラリの理解不能な動作

次のコードをコンパイルすると:

\documentclass[12pt]{article}

\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}


\begin{document}

\begin{tikzpicture}
\foreach \i in {(0,0),(0,2.1),(2.1,2.1),(2.1,0)} {
\fill[lightgray] \i rectangle ($(\i+(0.7,0.7)$); }
\draw (0,0) grid[step=0.7] (2.8,2.8);
\end{tikzpicture}

\end{document}

問題はなく、これで望みどおりの結果が得られます。ただし、「$」間の式が適切に括弧で囲まれていません。

$(\i+(0.7,0.7)$を に置き換えると、$\i+(0.7,0.7)$次のエラー メッセージが表示されます。

Runaway argument?
\i +(0.7,0.7)$); \pgffor@endhook \ifx \pgffor@assign@after@code \pgfutil@empty 
\ETC.
! Paragraph ended before \tikz@cc@parse@factor was complete.
<to be read again> 
               \par 
l.15 

または$(\i+(0.7,0.7)$に置き換えると、次のエラー メッセージが表示されます。$(\i+(0.7,0.7))$$(\i)+(0.7,0.7)$

! Package tikz Error: + or - expected.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.12 ...htgray] \i rectangle ($(\i)+(0.7,0.7)$); }

それはバグですか、それとも私が何か間違っているのでしょうか? (または単に奇妙な構文が正しいだけでしょうか?)

答え1

OPが挙げた例では、

\fill[lightgray] \i rectangle ($(\i+(0.7,0.7)$); 

(そしておそらくそうあるべきである)

\fill[lightgray] \i rectangle ++(0.7,0.7); 

ただし、これが MWE であり、実際のアプリケーションでcalcライブラリの使用が避けられない場合、これは (すでに指摘されているように) 拡張の問題になります。ライブラリcalcが使用されている場合は、次の方法が適している可能性があります。

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \i in {(0,0),(0,2.1),(2.1,2.1),(2.1,0)} {
\fill let \p1=\i in [lightgray] (\p1) rectangle ($(\p1)+(0.7,0.7)$); }
\draw (0,0) grid[step=0.7] (2.8,2.8);
\end{tikzpicture}
\end{document}

それでも

\fill let \p1=\i in [lightgray] (\p1) rectangle (\x1+.7, \y1+.7);

(私は)わずかに効率が良くなると思います。

ここに画像の説明を入力してください

しかし、危険な生活を送りたいなら、

\makeatletter
\def\pgffor@scanround(#1)#2,{\def\pgffor@value{#1#2}\pgffor@scanned}

プリアンブルで を使用します。その後、($(\i)+(0.7,0.7)$)foreach ループ内で を使用できます。

答え2

これはこれの偽物だと思うTikZ で数学を使う簡単に言うと、これは奇妙な相互作用で、コンテキストを正しくするために明示的な (したがって完全に展開された) 開き括弧が必要であり、\i構文を正しく終了するために閉じ括弧を使用します。別の括弧がつまずくのが見られた場合。適切な方法は、すべてを独自のコンテキストで括弧で囲み、かなり{}冗長にすることです。

ここでは、TeX と TikZ がトークンの解析についてどのように通信するかを示す優れたデモンストレーションを使用して、何が起こっているかを確認するためのより良い方法を示します (非常に直感的ではありませんが)。リストを含む特定の場所では括弧が欠落していることに注意してください。

このようなことが起こる主な理由は、TikZ がストリーム上で次の文字が何であるかを調べて分岐するためです。そのため、間違った場所に分岐し、その後に正しい用語を入力すると、戻って適切に分岐することはできません。このタイプのプログラミングでは、これらすべてを排除できるとは思いません。

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\foreach \i in {{(0,0},{(0,2.1},{(2.1,2.1},{(2.1,0}} {
\fill[lightgray] \i) rectangle ($(\i)+(0.7,0.7)$); }
\draw (0,0) grid[step=0.7] (2.8,2.8);
\end{tikzpicture}
\end{document}

ここに画像の説明を入力してください

答え3

ちなみに、余分な中括弧がなく、正しく一致する括弧で設定されている次のコードはコンパイルされ、期待どおりの結果が得られます。

\documentclass[12pt]{article}

\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{xinttools}

\begin{document}

% \begin{tikzpicture}
% \foreach \i in {(0,0),(0,2.1),(2.1,2.1),(2.1,0)} {
% \fill[lightgray] \i rectangle ($(\i+(0.7,0.7)$); }
% \draw (0,0) grid[step=0.7] (2.8,2.8);
% \end{tikzpicture}

\begin{tikzpicture}
\xintForpair  #1#2 in {(0,0),(0,2.1),(2.1,2.1),(2.1,0)} \do {
\fill[lightgray] (#1,#2) rectangle ($(#1,#2)+(0.7,0.7)$); }
\draw (0,0) grid[step=0.7] (2.8,2.8);
\end{tikzpicture}

\end{document}

答え4

これまでの解決策はすべて完璧です。そのうちのいくつかは、なぜ calc がコード内で混乱するのかを説明しています。また、いくつかは、foreach「ポイント」を通過する を使用できるようにするために何を変更する必要があるかを説明しています(x_i,y_i)

私の意見では、あなたの意見foreachは TikZ の精神では「間違っている」です。

  • \coordinate (A) at (x,y);と言うときはをA表しx,y、 ではなく(x,y)として使います(A)
  • let \p1=(x,y)と言うときはを\p1表しx,y、 ではなく(x,y)として使います(\p1)

だから、foreachポイントを突破したいときには、

\foreach \i in {{x_1,y_1},...,{x_n,y_n}}

そしてそれを として使用します(\i)

あなたの場合は次のようになります:

\documentclass[tikz,varwidth,border=5]{standalone}
\usetikzlibrary{calc}
\begin{document}
  \begin{tikzpicture}
    \foreach \i in {{0,0},{0,2.1},{2.1,2.1},{2.1,0}}
      \fill[lightgray] (\i) rectangle ($(\i)+(0.7,0.7)$); 
    \draw (0,0) grid[step=0.7] (2.8,2.8);
  \end{tikzpicture}
\end{document} 

ここに画像の説明を入力してください

関連情報