我正在尝试生成一个从 1 到 101 的数字螺旋,具有以下属性:
-- 5 的倍数位于五边形节点中
-- 3、6、11、13、17、23、29、37、43、52、56、61、63、68、69、71、72、80、91、99 号处有一个特殊的星爆节点。
(我认为shapes.geometric
如果我能弄清楚如何\x
在下面的循环中以特定值切换样式,就可以使用该库来实现这两个目标。)
这是我所在的地方(在这里):
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{stix}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{calc}
\usepackage{pifont}
\usepackage{wasysym}
\usepackage{graphicx}
\begin{document}
\hspace{0pt} \vfill
\begin{center}
\newcounter{cntRoot}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (0:1);
\foreach \x in {1,...,100}{%
\coordinate (c) at ($(b)!0.9cm!270:(a)$);
\setcounter{cntRoot}{\x}
\addtocounter{cntRoot}{1}
\node[fill=white,draw,circle,inner sep=1pt] at (c)
{$\thecntRoot$};
\coordinate (b) at (c);
};
\end{tikzpicture}
\end{center}
\vfill
\end{document}
我尝试实现这回答没有多大成功。任何帮助都将不胜感激!
答案1
我相信有更有效的方法来处理你的星爆(例如,使用LaTeX3),但下面的代码处理它们的方式是,首先定义一个逗号分隔的特殊数字列表,然后循环遍历所有数字以查看是否有匹配项。5
使用 可以轻松处理数字 mod \pgfmathparseresult
。
最终结果是:
以下是代码:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{stix}
\usepackage{tikz}
\usetikzlibrary{shapes,shapes.geometric,calc}
\usepackage{pifont}
\usepackage{wasysym}
\usepackage{graphicx}
\newif\ifnotfound% to mark the stars as we print them
\newcommand\starbursts{3,6,11,13,17,23,29,37,43,52,56,61,63,68,69,71,72,80,91,99}
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (0:1);
\foreach \x in {1,...,100}{%
\coordinate (c) at ($(b)!0.9cm!270:(a)$);
\pgfmathparse{int(mod(\x,5))}
\ifnum\pgfmathresult=0
\node[fill=white,draw,regular polygon, regular polygon sides=5,inner sep=1pt] at (c) {$\x$};
\else
\notfoundtrue% this will mark any starbursts
\foreach \y in \starbursts {% check for stars
\ifnum\x=\y% a star is born!
\node[fill=white,draw,starburst,inner sep=1pt] at (c) {$\x$};
\global\notfoundfalse% need \global as inside a loop
\fi
}
\ifnotfound% we have not printed a node yet
\node[fill=white,draw,circle,inner sep=1pt] at (c) {$\x$};
\fi
\fi
\coordinate (b) at (c);
};
\end{tikzpicture}
\end{document}
编辑
这是一个LaTeX3版本。代码更加简洁但从某种意义上说,它也比较慢,因为我的笔记本电脑返回以下时间:
tikz:实际 2.436 用户 2.136 系统 0.281 pcpu 99.18
tikz:实际 2.479 用户 2.169 系统 0.294 pcpu 99.34
解释:实际 2.557 用户 2.250 系统 0.293 PCPU 99.45
解释:实际 2.552 用户 2.238 系统 0.301 PCPU 99.49
输出与上面相同。以下是修改后的代码:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{stix}
\usepackage{tikz}
\usetikzlibrary{shapes,shapes.geometric,calc}
\usepackage{pifont}
\usepackage{wasysym}
\usepackage{graphicx}
\tikzset{
mynode/.style = {fill=white,draw,inner sep=1pt}
}
\usepackage{expl3}
\ExplSyntaxOn
\clist_new:N \l_starbursts
\clist_set:Nn \l_starbursts {3,6,11,13,17,23,29,37,43,52,56,61,63,68,69,71,72,80,91,99}
\newcommand\SetNode[1]{
\int_compare:nTF { \int_mod:nn { #1 } { 5 } = 0 }
{\tikzset{mynode/.append~style={regular~polygon, regular~polygon~sides=5}}}
{
\clist_if_in:NoTF \l_starbursts {#1}
{\tikzset{mynode/.append~style={starburst}}}
{\tikzset{mynode/.append~style={circle}}}
}
}
\cs_generate_variant:Nn \clist_if_in:NnTF {noTF}
\ExplSyntaxOff
\newif\ifnotfound% to mark the stars as we print them
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (0:1);
\foreach \x in {1,...,100}{%
\coordinate (c) at ($(b)!0.9cm!270:(a)$);
\SetNode{\x}
\node[mynode] at (c) {$\x$};
\coordinate (b) at (c);
};
\end{tikzpicture}
\end{document}
编辑二
这是遵循 jfbu 建议的第三种“纯 TeX”方法,其中星号优先于六边形(与上面不同,正如 sgmoye 在评论中指出的那样)。我改用纯 TeX,因为令人惊讶的是,以类似的方式使用 LaTeX3 序列会导致代码速度变慢。也许 clists 会更好?也可能是第一个解决方案直接绘制节点,而解决方案 II 和 III 使用了一些\tikzset{...}
技巧。无论如何,这是代码:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{stix}
\usepackage{tikz}
\usetikzlibrary{shapes,shapes.geometric,calc}
\usepackage{pifont}
\usepackage{wasysym}
\usepackage{graphicx}
\tikzset{
mynode/.style = {fill=white,draw,inner sep=1pt}
}
\newcommand\starbursts{3,6,11,13,17,23,29,37,43,52,56,61,63,68,69,71,72,80,91,99}
\def\setnextstar#1,#2!{%
\if\relax\detokenize{#1}\relax\gdef\nextstar{200}\else\gdef\nextstar{#1}\gdef\starbursts{#2}\fi%
}
\expandafter\setnextstar\starbursts,,!
\newcommand\SetNode[1]{
\ifnum#1=\nextstar
\tikzset{mynode/.append style={starburst}}
\expandafter\setnextstar\starbursts!
\else
\pgfmathparse{int(mod(\x,5))}
\ifnum\pgfmathresult=0
\tikzset{mynode/.append style={regular polygon, regular polygon sides=5}}
\else
\tikzset{mynode/.append style={circle}}
\fi
\fi
}
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (0:1);
\foreach \x in {1,...,100}{%
\coordinate (c) at ($(b)!0.9cm!270:(a)$);
\SetNode{\x}
\node[mynode] at (c) {$\x$};
\coordinate (b) at (c);
};
\end{tikzpicture}
\end{document}
输出略有不同,因为80
现在有一个星号。