
Игнасисоздал отличный код для блоков счисления с основанием 10 и пытаюсь использовать его для автоматической генерации представлений двузначных чисел.
%%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}
автоматически создавал похожую картинку. (Где единицы идут первыми, чтобы обеспечить больше позиций разрядов, например, \basetenpic{2}{0}{3}
это создало бы картинку с тремя сотнями, за которыми следуют две единицы...)
У кого-нибудь есть идеи?
решение1
Адаптации
- определенные длины
\unitsize
и\unitsep
- использовать
foreach
для рисования узлов - используйте
\ifnumgreater{\tens}{0}{}{}
и т. д., чтобы проверить, какие блоки следует нарисовать - Я также думал об использовании только числа в качестве одного параметра, как расширения, но потом увидел, что это уже сделано в ответе Джаспера. Поэтому я просто добавил функцию-обертку
\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
Я думаю, что даже более удачным подходом, чем иметь макрос, принимающий один, два или три аргумента, было бы просто позволить PGF делать математику. Таким образом, вы просто вводите произвольные числа от 1 до 999 в единственный аргумент макроса, \basetenpic
и количество ящиков будет рассчитано автоматически.
Я бы также, вероятно, скорректировал размеры ячеек и промежутков так, чтобы 10 меньших ячеек (включая промежутки) имели такую же ширину или высоту, как одна большая ячейка. (Конечно, как указал @dexteritas, невозможно сопоставить площади разных ячеек и значения, которые они представляют, и в то же время иметь 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 раз больше площади одной маленькой ячейки и т. д.). Однако, ради единообразия, я бы удалил пробелы вообще. Вы можете изменить часть \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,
}
}
}
Пример результата: