我的目的很简单:用来tikzpictures
绘制数字表,数字被画在形状奇特的彩色方框内,不同的数字有不同的形状和颜色。下面我根据数字是奇数、偶数还是质数来给它们装框(并将 1 视为特殊数字)。
这个想法是利用颜色和形状来发现模式。我最初的计划是用它来教素数,但后来我想到了其他有趣的事情。
由于我刚开始使用tikz
(只用了几天),所以仍然有一些基本的东西我不明白。以下是我想对下面显示的基本表格进行的改进和修改。
将形状调整为大致相同的“大小”
对于这可能意味着什么,有几种解释,任何合理的解释都可以。目前,方框会根据数字的大小进行调整,一位数的方框较小,两位数的方框较大,三位数的方框更大。我希望数字缩小而不是方框缩小。您还可以看到,我很难让形状与
star
其他形状对齐。我确实摆弄了anchor
、inner sep
和outer sep
,但这就是我目前所知道的全部。控制数字运行的方向
应广大民众的要求,我把这个问题作为一个单独的问题来问:Tikz 节点顺序和具有一般节点数的形状
为了清楚起见,我将生成不同大小的表格,有的有 10 个数字,有的有 100 个数字,可能更多,有的有更长的行,有的有更长的列,并且我希望形状能够自动按比例调整大小。
我还没有仔细考虑过形状和颜色的选择,这只是初步尝试。请随意美化 ;-)
这是迄今为止的代码:
\RequirePackage[svgnames,x11names]{xcolor}
\documentclass[tikz,convert=false,margin=0pt]{standalone}%
\usetikzlibrary{shapes.geometric}% polygon, ellipse, star, diamond, etc.
\usepackage{tkz-euclide}% \pgfmathisprime command
\usepackage{rotating}% sideways environment
\begin{document}%
\begin{tikzpicture}[%
every node/.style = {
shape = circle
, align = center
, scale = 2
, anchor = base
, font = \fontfamily{pzc}\selectfont% common font
} ,
% Prime Numbers
PrimeStyle/.style = {
regular polygon
, regular polygon sides = 3
, rounded corners = .5em
, inner sep = 0pt
, outer sep = 0pt
, draw = DarkGreen, thick
, fill = green!70!black
, text = white
} ,
% Even Numbers
EvenStyle/.style = {
shape = circle
, inner sep = 2pt
, draw = DarkRed, thick
, fill = red!70!black
, text = white
} ,
% Non-Prime Odd Numbers
OddStyle/.style = {
shape = diamond
, rounded corners = .5em
, inner sep = 1pt
, draw = DarkBlue, thick
, fill = blue!70!black
, text = white
} ,
% Number One
OneStyle/.style = {
shape = star
, rounded corners = .5em
, inner sep = 2pt
, scale = 0.9
, draw = white!70!black, thick
, fill = blue!50!green!50!
, text = black
}
]%
%
% Set Grid Dimensions
\newcommand{\xa}{1}
\newcommand{\xb}{10}
\newcommand{\ya}{1}
\newcommand{\yb}{10}
\pgfmathsetmacro{\yc}{\yb-1}% \yb minus one
%
% Change styles of numbers according to set membership
\foreach \x in {\xa,...,\xb}
\foreach \y in {\ya,...,\yb}
{\pgfmathtruncatemacro{\label}{\x - \xb * (\y - \yb) }
\pgfmathparse{int(mod(\label,2))}
\let \r \pgfmathresult
\ifnum \r = 1
\tikzset{EvenStyle/.style = {OddStyle}}
\fi
\pgfmathisprime{int(\label)}
\let \s \pgfmathresult
\ifnum \s = 1
\tikzset{EvenStyle/.style = {PrimeStyle}}
\fi
\pgfmathparse{int(\label)}
\let \t \pgfmathresult
\ifnum \t = 1
\tikzset{EvenStyle/.style = {OneStyle}}
\fi
\node [EvenStyle] (\x\y) at (1.5*\x, -1.5*\y) {\label};}
\foreach \x in {\xa,...,\xb}
\foreach \y [count = \yi] in {\ya,...,\yc}
\draw (\x\y)(\x\yi) (\y\x)(\yi\x) ;
\end{tikzpicture}%
\end{document}%
% doesn't work, why?
% \foreach \k in {1,2,3,5,7,11,13}
% \tikzset{EvenStyle/.style = {PrimeStyle}} ;
这是该问题的直接前身:
寻找大量数字代码的优雅与便捷
Harish Kumar 在那里向我展示了如何使用foreach
循环编写通用代码。
在这里我了解了一种稍微不同的定义网格的方法: 选择特定节点并更改样式(针对这些节点)
\pgfmathisprime
这是我从包中了解到该命令的地方tikz-euler
:
如何在 LaTeX 中生成素数列表
在这里我看到了几个例子之一,从中我学会了如何使用ifnum
withint
和mod
and \pgfmathparse
:
如何在 latex 和 tikz 中使用 mod 操作
答案1
我不确定这是否回答了您的所有问题,但我认为以下内容(尽管并不完美)显示了一些可以简化代码的方法。不过我认为总会涉及一些手动调整(例如,设置适当的inner sep
)。
\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{shapes.geometric}
\begin{document}
\tikzset{%
set color/.style={
fill=#1,
draw=#1!50!black
},
every number/.style={
text=white,
rounded corners=0.125cm,
font=\fontfamily{pzc}\selectfont,
text width=3ex,
align=center,
scale=2
},
every prime number/.style={
shape=diamond,
set color=blue!70!black,
inner sep=0.25ex,
},
every even number/.style={
shape=circle,
set color=red!70!black,
inner sep=0.5ex
},
every odd number/.style={
shape=regular polygon,
regular polygon sides=3,
set color=green!70!black,
inner sep=-0.375ex
},
number 1/.style={
shape=star,
set color=green!50!blue,
inner sep=-.25ex
}
}%
\begin{tikzpicture}[x=2cm, y=2cm]
\foreach \n [evaluate={%
\x=mod(\n-1,10);
\y=floor((\n-1)/10);
\p=isprime(\n);
\e=mod(\n,2)==0;
\style=(\p || \n==2) ? "prime" : (\e ? "even" : "odd");}] in {1,...,100}
\node [every number/.try, every \style\space number/.try, number \n/.try]
at (\x,\y) {\n};
\end{tikzpicture}
\end{document}
答案2
我从您的回答中学到了很多东西,非常感激。作为结语,我想指出,在我提出问题时我还没有看到的一个帖子中,Paul Gaborit 展示了如何追踪螺旋路径。这是在埃拉托斯特尼筛法的背景下:我意识到,设计我想要的那种板子有着悠久的历史:乌拉姆螺旋、萨克斯螺旋等。令人惊叹的东西:
我改编了几位贡献者慷慨分享的各种代码,以获得以下内容,即使不是因为其新颖性,也仅供记录之用:
\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{shapes.geometric}% polygon, ellipse, star, diamond, etc.
\usetikzlibrary{shapes.symbols}% starburst,
\usetikzlibrary{shadows}
\usetikzlibrary{shadings}
% Needs development version of PGF/TikZ
% Unpack pgf_CVS.ds.zip inside: Users/UserName/Library/texlive/2013/texmf-var
\begin{document}
% Set Grid Dimensions
\newif\ifcurrent\currenttrue
\ifcurrent
\newcommand{\na}{0}% first number
\newcommand{\nb}{30}% last number
\newcommand{\nn}{0.5}% tweak scale
\fi
\newcommand{\ns}{0}% special number, irregular star shape
\tikzset{%
set color/.style = {
fill = #1,
draw = #1!50!black,
},
every number/.style = {
opacity = 0.9,
drop shadow,
inner sep = 0.25ex,
text = white,
font = \fontfamily{pzc}\selectfont,
align = center,
scale = \nn
},
every even number/.style = {
set color = blue!70!black,
shape = circle,
inner sep = 1ex
},
every odd number/.style = {
set color = blue!70!black,
shape = diamond,
inner sep = 1.2ex
},
every prime number/.style = {
set color = red!70!black,
shape = diamond,
inner sep = 1.2ex,
},
number 2/.style = {
set color = red!70!black,
shape = circle,
inner sep = 1ex
},
special number \ns/.style = {
shape = starburst,
starburst points = 7,
drop shadow,
set color = green!50!blue,
inner sep = 1ex
},
every dot/.style ={
set color = green!50!blue
}
}%
\begin{tikzpicture}
\coordinate (last);
\foreach \n [evaluate={%
% \style: \p for prime, \e for even
% x ? y : z means "if x then y else z"
\p = isprime(\n);
\e = mod(\n,2)==0;
\style= \p ? "prime" : (\e ? "even" : "odd");
% \coordinate: \r for radius, \a for angle
\r = sqrt(\n)/2;
\a = sqrt(\n)*360;
}] in {\na,...,\nb}{%
\coordinate(new) at (\a:\r);
\draw[every dot/.try] (last) to[bend right={6/sqrt(\n)}] (new);
\node[every number/.try, every \style\space number/.try, number \n/.try,
special number \n/.try, minimum size=1cm](last) at (\a:\r) {\n};
}%
\end{tikzpicture}
\end{document}