10進ブロックを描画するための新しいコマンドを作成する

10進ブロックを描画するための新しいコマンドを作成する

イグナシ10 進ブロック用の素晴らしいコードをいくつか作成したので、それを使用して 2 桁の数字の表現を自動的に生成しようとしています。

%%Base 10 Blocks
\tikzset {
    node distance=.1cm,
    hundred/.style={
        draw,
        minimum size=1cm,
        inner sep=0pt
        },
    tenv/.style={
        line width=0.1mm,
        fill=red,
        draw,
        minimum height=1cm,
        minimum width=0.1cm,
        inner sep=0pt,
    },
    tenthh/.style={
        draw,
        minimum height=0.1cm,
        minimum width=1cm,
        inner sep=0pt,
    },
    unitone/.style={
         line width=0.1mm,
        draw,
        minimum size=0.1cm,
        inner sep=0pt,
    },
   base graph/.pic={
        \node[hundred] (00) {};
        \node[hundred, below=of 00] (10) {};
        \node[tenthh, below=of 10] (20) {};
        \foreach \i [count=\xi, remember=\xi as \lasti (initially 0)] in {1,2,3,4} 
          \node[tenv, right=of 0\lasti] (0\xi) {};         
        \path (00.north west) -- (20.south west) node[midway, left] {2.1} ;
        \path (00.north west) -- (04.north east) node[midway, above] {1.4} ;
        }
    }

37という数字を生成するために私が作ったコードは次のとおりです。

 \begin{center} \begin{tikzpicture}[transform canvas={scale=3}]
 \foreach \y in {-0.95,-0.85,...,-0.35}{
 \node[unitone] at (0.1,\y){};}
 \foreach \x in {-0.5,-0.3,...,-0.1}{
 \node[tenv] at (\x,-0.5){};}
 \end{tikzpicture}\end{center}

見た目はまさにその通りです...

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

ただし、非常に扱いにくく、Excel で作成されました。

自動的に同様の画像を作成するようなコードがあればいいなと思います\basetenpic{7}{3}。(1 の位の値が最初に来るようにすると、より多くの位の値の位置が可能になります。たとえば、\basetenpic{2}{0}{3}3 つの 100 の位の後に 2 つの 1 の位の値が続く画像が作成されます...)

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

誰か何かアイデアはありますか?

答え1

適応

  • 定義された長さ\unitsize\unitsep
  • foreachノードを描画するために使用する
  • \ifnumgreater{\tens}{0}{}{}どのブロックを描画するかを確認するには、などを使用します。
  • 拡張機能として、数値を 1 つのパラメーターとして使用することも考えましたが、これは Jasper の回答ですでに実行されていることがわかりました。そこで、ラッパー関数を追加しました\basetenpicx{<number>}

結果

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

コード

\documentclass{article}

\usepackage{etoolbox}
\usepackage{tikz}

\newlength{\unitsize}
\setlength{\unitsize}{3mm}

\newlength{\unitsep}
\setlength{\unitsep}{3mm}

% Base 10 Blocks
\tikzset {
    node distance=\unitsep,
    hundred/.style={
        draw,
        fill=yellow,
        anchor=south west,
        minimum size=10*\unitsize,
        inner sep=0pt
    },
    tenv/.style={
        anchor=south west,
        line width=0.1mm,
        fill=red,
        draw,
        minimum height=10*\unitsize,
        minimum width=\unitsize,
        inner sep=0pt,
    },
    tenthh/.style={
        anchor=south west,
        draw,
        minimum height=\unitsize,
        minimum width=10*\unitsize,
        inner sep=0pt,
    },
    unitone/.style={
        anchor=south west,
        line width=0.1mm,
        draw,
        minimum size=\unitsize,
        inner sep=0pt,
    },
}

\newcommand{\basetenpic}[3]{
    \edef\ones{#1}
    \edef\tens{#2}
    \edef\hundreds{#3}
    \begin{tikzpicture}
        % uncomment this to have the same height
        %\node[inner sep=0pt] at (0,10*\unitsize) {};
        % one
        \ifnumgreater{\ones}{0}{
            \foreach \i in {1, ..., \ones}{
                \node[unitone] at ({\hundreds*(10*\unitsize+\unitsep) + \tens*(\unitsize+\unitsep)}, {(\i-1)*\unitsize}) {};
            }
        }{}
        % ten
        \ifnumgreater{\tens}{0}{
            \foreach \i in {1, ..., \tens}{
                \node[tenv] at ({\hundreds*(10*\unitsize+\unitsep) + (\i-1)*(\unitsize+\unitsep)}, 0) {};
            }
        }{}
        % hundret
        \ifnumgreater{\hundreds}{0}{
            \foreach \i in {1, ..., \hundreds}{
                \node[hundred] at ({(\i-1)*(10*\unitsize+\unitsep)}, 0) {};
            }
        }{}
    \end{tikzpicture}   
}

\newcommand{\basetenpicx}[1]{
    \pgfmathtruncatemacro{\ones}{mod(#1, 10)}
    \pgfmathtruncatemacro{\tens}{mod(#1 - \ones, 100)/10}
    \pgfmathtruncatemacro{\hundreds}{mod(#1 - \tens - \ones, 1000)/100}
    \basetenpic{\ones}{\tens}{\hundreds}
}

\begin{document}

\obeylines
\verb|\basetenpic{7}{0}{0}|:
\basetenpic{7}{0}{0}

\verb|\basetenpic{7}{3}{0}|:
\basetenpic{7}{3}{0}

\verb|\basetenpicx{203}|:
\basetenpicx{203}

\verb|\basetenpicx{60}|:
\basetenpicx{60}

\end{document}

答え2

1 つ、2 つ、または 3 つの引数を受け入れるマクロを使用するよりもさらに良い方法は、PGF に計算を任せることだと思います。この方法では、マクロの単一の引数に 1 から 999 までの任意の数字を入力するだけで\basetenpic、ボックスの数が自動的に計算されます。

また、ボックスとギャップのサイズを調整して、10 個の小さいボックス (ギャップを含む) の幅または高さが 1 つの大きいボックスと同じになるようにします。(もちろん、@dexteritas が指摘したように、ギャップを含む 10 個の 1 ボックスを 1 つの 10 ボックスの高さに一致させながら、異なるボックスの面積とそれらが表す値を一致させることは不可能です。)

次のようにすると、このようなボックスが出力されます。好みに応じて、さまざまなボックスのスタイルを設定できます。たとえば、ボックスを黄色に塗りつぶすなどです。マクロは、tikzpictureスタイル設定にカスタム オプションを追加するためのオプションの引数を取ります。

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\tikzset{
    basetenpic/.style={
        node distance=0.05cm,
        every node/.style={
            draw,
            line width=0.01cm,
            inner sep=0pt,
        },
        hundreds/.style={
            % = 10 x height of boxes + 9 x line width + 9 x gap
            % = 10 x 0.1cm + 9 x 0.01cm + 9 x 0.05cm
            minimum size=1.54cm,
        },
        tens/.style={
            minimum height=1.54cm,
            minimum width=0.1cm,
        },
        ones/.style={
            minimum size=0.1cm,
        }
    }
}

\newcounter{boxcount}
\newcommand{\basetenpic}[2][]{
    \pgfmathtruncatemacro{\ones}{mod(#2, 10)}
    \pgfmathtruncatemacro{\tens}{mod(#2 - \ones, 100)/10}
    \pgfmathtruncatemacro{\hundreds}{mod(#2 - \tens - \ones, 1000)/100}
    \setcounter{boxcount}{0}
    \begin{tikzpicture}[basetenpic, #1]
        \coordinate (n0) at (0,0);
        \ifnum\hundreds>0\relax
            \foreach \i [evaluate={\theboxcount as \lastboxcount}] in {1,...,\hundreds} {
                \stepcounter{boxcount}
                \node[right=of n\lastboxcount, hundreds] (n\theboxcount) {};
            }
        \fi
        \ifnum\tens>0\relax
            \foreach \i [evaluate={\theboxcount as \lastboxcount}] in {1,...,\tens} {
                \stepcounter{boxcount}
                \node[right=of n\lastboxcount, tens] (n\theboxcount) {};
            }
        \fi
        \ifnum\ones>0\relax
            \foreach \i [evaluate={\theboxcount as \lastboxcount}] in {1,...,\ones} {
                \stepcounter{boxcount}
                \ifnum\i=1\relax
                    \node[right=of n\lastboxcount.south east, anchor=south west, ones] (n\theboxcount) {};
                \else
                    \node[above=of n\lastboxcount, ones] (n\theboxcount) {};
                \fi
            }
        \fi
    \end{tikzpicture}
}

\begin{document}
    
\basetenpic{26}

\basetenpic{302}

\basetenpic[hundreds/.append style={fill=yellow}]{137}

\end{document}

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

リンク先の元の回答では が作成されますpicが、このソリューションでは完全な が出力されますtikzpicture。ただし、一方を別の に変換するのはそれほど複雑ではありません。


隙間をなくすと、ボックスの面積は互いに正確な関係になります (つまり、10 の位のボックスは 1 つの小さなボックスの面積の 10 倍になります)。ただし、一貫性を保つために、隙間はすべて取り除きます。\tikzset上記の MWE の部分は、次のように変更できます。

\tikzset{
    basetenpic/.style={
        % = minus half the line width    
        node distance=-0.005cm,
        every node/.style={
            draw,
            line width=0.01cm,
            inner sep=0pt,
        },
        hundreds/.style={
            minimum size=1cm,
        },
        tens/.style={
            minimum height=1cm,
            minimum width=0.1cm,
        },
        ones/.style={
            minimum size=0.1cm,
        }
    }
}

結果例:

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

関連情報