节日来临,我们当然都会拿出自己最喜欢的 TikZ光明节烛台庆祝一下。然而,我们的孩子仍然不满足,他们要求在漫长的黑暗夜晚做点活动。尽管我们试图为他们提供下载的连点拼图,但他们很快就意识到没有在 TikZ 中制作。
我们能否通过提供色彩缤纷的连点光明节烛台(甚至是陀螺)来消磨时间,从而挽救这种情况?
这是光明节(Hanukiah)的无色示例(嗯...实际上是犹太烛台,因为其蜡烛数量与光明节不符,应为八加一)。
这是无色的陀螺样品。
答案1
好的,加上一点点颜色,这是一个join the dots
装饰:
\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\newcount\tikzjointhedotsnumber
\pgfdeclaredecoration{join the dots}{initial}{%
\state{initial}[width=0pt, next state=do dots, persistent precomputation={\global\tikzjointhedotsnumber=1}]{}
%
\state{do dots}[width=\pgfdecoratedinputsegmentlength, persistent postcomputation={\global\advance\tikzjointhedotsnumber by1}]{%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
}
%
\state{final}{%
% Is the last point the same as the first?
\pgfpointdiff{\pgfpointdecoratedpathlast}{\pgfpointdecoratedpathfirst}%
\pgfmathveclen{\the\pgf@x}{\the\pgf@y}%
\ifdim\pgfmathresult pt=0pt\relax%
\global\advance\tikzjointhedotsnumber by-1\relax
\else
\pgftransformshift{\pgfpointdecoratedpathlast}%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
\fi
% Ok, now we do everything. Draw the dots and place the numbers.
%
\c@pgf@counta=\tikzjointhedotsnumber%
\c@pgf@countb=2\relax%
\edef\lastdot{\the\tikzjointhedotsnumber}%
\def\nextdot{2}%
\pgftransformreset%
\pgfmathloop%
\ifnum\pgfmathcounter>\tikzjointhedotsnumber
\else%
% Draw the dot.
\edef\tmp{\the\tikzjointhedotsnumber}%
\tikzjointhedotsnumber=\pgfmathcounter\relax%
\path [shift={(@dot-\pgfmathcounter)}, every dot/.try, dot \pgfmathcounter/.try];
\tikzjointhedotsnumber=\tmp%
%
% Calculate the dot number node anchor
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@counta}{center}}%
\pgf@xc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@xc%
\advance\pgf@xc by360pt\relax%
\fi%
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@countb}{center}}%
\pgf@yc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@yc%
\advance\pgf@yc by360pt\relax%
\fi%
\ifdim\pgf@xc>\pgf@yc%
\pgf@x=360pt\relax%
\else%
\pgf@x=0pt\relax%
\fi%
\advance\pgf@x by-\pgf@xc%
\advance\pgf@x by\pgf@yc%
\divide\pgf@x by2\relax%
\advance\pgf@x by\pgf@xc%
\advance\pgf@x by180pt\relax%
\edef\dotnumberanchor{\the\pgf@x}%
\node [anchor=\dotnumberanchor, every dot number/.try, dot number \pgfmathcounter/.try]
at (@dot-\pgfmathcounter)
{\tikzjointhedotsnumber=\pgfmathcounter\relax\tikzjointhedotstypesetnumber{\tikzjointhedotsnumber}};
\c@pgf@counta=\pgfmathcounter\relax%
\advance\c@pgf@countb by1\relax%
\ifnum\c@pgf@countb>\tikzjointhedotsnumber%
\c@pgf@countb=1\relax%
\fi%
\repeatpgfmathloop%
}
}
% Command for typesetting dot number
% #1 - a count register holding the current dot number
%
\def\tikzjointhedotstypesetnumber#1{\the#1}
\makeatletter
% Keys for setting dot number styles
\tikzset{%
syle dot number range/.code args={#1 to #2 with #3}{%
\c@pgf@counta=#1
\pgfmathloop
\ifnum\c@pgf@counta>#2\relax%
\else%
\tikzset{dot number \the\c@pgf@counta/.style={#3}}%
\advance\c@pgf@counta by1
\repeatpgfmathloop%
},
style dot number list/.code args={#1 with #2}{%
\pgfutil@for\tmp:=#1\do{%
\tikzset{dot number \tmp/.style={#2}}%
}%
}
}
\makeatother
\tikzset{%
% Executed for every dot
every dot/.style={fill=black,
insert path={ circle [radius=.75mm] coordinate [alias=dot-last] (dot-\the\tikzjointhedotsnumber) }
},
% Executed for every dot number
every dot number/.style={
shape=circle,
font=\footnotesize\sf,
},
join the dots/.style={
decoration=join the dots, decorate
},
lines/.style={
ultra thick,
line join=round,
line cap=round
},
crayon/.style={
draw=#1,
line join=round,
line cap=round,
line width=1mm
},
sketch/.style={
bend right, out=rand*10, in=180-rand*10
}
}
\begin{document}
\begin{tikzpicture}
% Draw and number the dots
\path [postaction={join the dots}]
(-1/2,11)
\foreach \a [count=\c from 1, evaluate={\d=\a+1;\s=90/\d;}] in {1,2,3,4}{
-- ++(0,{\a==1?-2:-1})
\foreach \i in {1,...,\d}{
arc (270-\i*\s+\s:270-\i*\s:\a*2-1 and \a*3/2-1/2)
}
-- ++(-1,0) coordinate [midway] (candle-\c)
\foreach \i in {1,...,\d}{
arc (180+\i*\s-\s:180+\i*\s:\a*2 and \a*3/2)
}
}
-- ++(0,-1)
-| ++(-1,-1/2) -| ++(-1,-1/2) -| ++(-1,-1/2)
-- ++(7,0)
|- ++(-1,1/2) |- ++(-1,1/2) |- ++(-1,1/2)
\foreach \a [count=\c from 5, evaluate={\d=\a+1;\s=90/\d;}] in {4,3,2,1}{
-- ++(0,1)
\foreach \i in {1,...,\d}{
arc (270+\i*\s-\s:270+\i*\s:\a*2 and \a*3/2)
}
-- ++(-1,0) coordinate [midway] (candle-\c)
\foreach \i in {1,...,\d}{
arc (360-\i*\s+\s:360-\i*\s:\a*2-1 and \a*3/2-1/2)
}
}
-- ++(0,2);
% Draw the lines that are visible.
\draw [lines]
(dot-1) -- (dot-last) coordinate [midway] (candle-9);
% Draw candles
\foreach \cn in {1,...,9}{%
\tikzset{shift=(candle-\cn), yshift=1pt}%
% Candle
\fill [lines, fill=purple!80, rounded corners=0.125cm]
(-1/3,0) to [sketch] (-1/3,3) -- (1/3,3) to [sketch] (1/3,0);
% Wick
\draw [lines] (0,3) -- ++(0,1/4);
\tikzset{shift={(0,3+1/8)}, xscale=round(rnd)*2-1,yscale=1+rand/8}
\foreach \s/\c in {1/yellow,.5/red}
\path [lines, fill=\c!50!orange, opacity=3/4, scale=\s]
(0,0)
arc (270:180:3/8)
.. controls ++(0,1/4) and ++(0,-1/4) .. (0,3/2)
arc (90:0:3/8 and 1) arc (360:270:3/8 and 1/2);
}
\end{tikzpicture}%
\end{document}
这需要长的编译时间。
\documentclass[border=0.125cm]{standalone}
\standaloneenv{minipage}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\newcount\tikzjointhedotsnumber
\pgfdeclaredecoration{join the dots}{initial}{%
\state{initial}[width=0pt, next state=do dots, persistent precomputation={\global\tikzjointhedotsnumber=1}]{}
%
\state{do dots}[width=\pgfdecoratedinputsegmentlength, persistent postcomputation={\global\advance\tikzjointhedotsnumber by1}]{%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
}
%
\state{final}{%
% Is the last point the same as the first?
\pgfpointdiff{\pgfpointdecoratedpathlast}{\pgfpointdecoratedpathfirst}%
\pgfmathveclen{\the\pgf@x}{\the\pgf@y}%
\ifdim\pgfmathresult pt=0pt\relax%
\global\advance\tikzjointhedotsnumber by-1\relax
\else
\pgftransformshift{\pgfpointdecoratedpathlast}%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
\fi
% Ok, now we do everything. Draw the dots and place the numbers.
%
\c@pgf@counta=\tikzjointhedotsnumber%
\c@pgf@countb=2\relax%
\edef\lastdot{\the\tikzjointhedotsnumber}%
\def\nextdot{2}%
\pgftransformreset%
\pgfmathloop%
\ifnum\pgfmathcounter>\tikzjointhedotsnumber
\else%
% Draw the dot.
\edef\tmp{\the\tikzjointhedotsnumber}%
\tikzjointhedotsnumber=\pgfmathcounter\relax%
\path [shift={(@dot-\pgfmathcounter)}, every dot/.try, dot \pgfmathcounter/.try];
\tikzjointhedotsnumber=\tmp%
%
% Calculate the dot number node anchor
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@counta}{center}}%
\pgf@xc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@xc%
\advance\pgf@xc by360pt\relax%
\fi%
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@countb}{center}}%
\pgf@yc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@yc%
\advance\pgf@yc by360pt\relax%
\fi%
\ifdim\pgf@xc>\pgf@yc%
\pgf@x=360pt\relax%
\else%
\pgf@x=0pt\relax%
\fi%
\advance\pgf@x by-\pgf@xc%
\advance\pgf@x by\pgf@yc%
\divide\pgf@x by2\relax%
\advance\pgf@x by\pgf@xc%
\advance\pgf@x by180pt\relax%
\edef\dotnumberanchor{\the\pgf@x}%
\node [anchor=\dotnumberanchor, every dot number/.try, dot number \pgfmathcounter/.try]
at (@dot-\pgfmathcounter)
{\tikzjointhedotsnumber=\pgfmathcounter\relax\tikzjointhedotstypesetnumber{\tikzjointhedotsnumber}};
\c@pgf@counta=\pgfmathcounter\relax%
\advance\c@pgf@countb by1\relax%
\ifnum\c@pgf@countb>\tikzjointhedotsnumber%
\c@pgf@countb=1\relax%
\fi%
\repeatpgfmathloop%
}
}
% Command for typesetting dot number
% #1 - a count register holding the current dot number
%
\def\tikzjointhedotstypesetnumber#1{\the#1}
\makeatletter
% Keys for setting dot number styles
\tikzset{%
syle dot number range/.code args={#1 to #2 with #3}{%
\c@pgf@counta=#1
\pgfmathloop
\ifnum\c@pgf@counta>#2\relax%
\else%
\tikzset{dot number \the\c@pgf@counta/.style={#3}}%
\advance\c@pgf@counta by1
\repeatpgfmathloop%
},
style dot number list/.code args={#1 with #2}{%
\pgfutil@for\tmp:=#1\do{%
\tikzset{dot number \tmp/.style={#2}}%
}%
}
}
\makeatother
\tikzset{%
% Executed for every dot
every dot/.style={fill=black,
insert path={ circle [radius=.75mm] coordinate [alias=dot-last] (dot-\the\tikzjointhedotsnumber) }
},
% Executed for every dot number
every dot number/.style={
shape=circle,
font=\footnotesize\sf,
},
join the dots/.style={
decoration=join the dots, decorate
},
lines/.style={
ultra thick,
line join=round,
line cap=round
},
crayon/.style={
draw=#1,
line join=round,
line cap=round,
line width=1mm
},
sketch/.style={
bend right, out=rand*10, in=180-rand*10
}
}
\begin{document}
% Put (most of) the picture in a box, so it doesn't
% have to be redrawn every iteration.
\newbox\hanukkahbox
\setbox\hanukkahbox=\hbox{%
\begin{tikzpicture}[baseline={(0,0)}]
% Draw and number the dots
\path [postaction={join the dots}]
(-1/2,11)
\foreach \a [count=\c from 1, evaluate={\d=\a+1;\s=90/\d;}] in {1,2,3,4}{
-- ++(0,{\a==1?-2:-1})
\foreach \i in {1,...,\d}{
arc (270-\i*\s+\s:270-\i*\s:\a*2-1 and \a*3/2-1/2)
}
-- ++(-1,0) coordinate [midway] (candle-\c)
\foreach \i in {1,...,\d}{
arc (180+\i*\s-\s:180+\i*\s:\a*2 and \a*3/2)
}
}
-- ++(0,-1)
-| ++(-1,-1/2) -| ++(-1,-1/2) -| ++(-1,-1/2)
-- ++(7,0)
|- ++(-1,1/2) |- ++(-1,1/2) |- ++(-1,1/2)
\foreach \a [count=\c from 5, evaluate={\d=\a+1;\s=90/\d;}] in {4,3,2,1}{
-- ++(0,1)
\foreach \i in {1,...,\d}{
arc (270+\i*\s-\s:270+\i*\s:\a*2 and \a*3/2)
}
-- ++(-1,0) coordinate [midway] (candle-\c)
\foreach \i in {1,...,\d}{
arc (360-\i*\s+\s:360-\i*\s:\a*2-1 and \a*3/2-1/2)
}
}
-- ++(0,2);
% Draw the lines that are visible.
\draw [lines]
(dot-1) -- (dot-last) coordinate [midway] (candle-9);
\end{tikzpicture}}%
%
\foreach \k in {1,...,88}{%
\begin{minipage}{\wd\hanukkahbox}%
\begin{tikzpicture}
% Place the picture box.
\pgftext[bottom]{\copy\hanukkahbox}%
% Draw candles
\foreach \cn in {1,...,9}{%
\tikzset{shift=(candle-\cn), yshift=1pt}
% Set the random seed as fixed with the candle number as
% a parameter so that candles are different from each
% other, but drawn the same on each outer iteration.
\pgfmathsetseed{99+\cn*50}%
% Candle
\fill [lines, fill=purple!80, rounded corners=0.125cm]
(-1/3,0) to [sketch] (-1/3,3) -- (1/3,3) to [sketch] (1/3,0);
% Wick
\draw [lines] (0,3) -- ++(0,1/4);
% Ensure highest point for bounding box
\path (candle-9) -- ++(0,5);
\pgfmathsetseed{99+\k*50+\cn*25}%
\tikzset{shift={(0,3+1/8)}, xscale=round(rnd)*2-1,yscale=1+rand/8}
\foreach \s/\c in {1/yellow,.5/red}
\path [lines, fill=\c!50!orange, opacity=3/4, scale=\s]
(0,0)
arc (270:180:3/8)
.. controls ++(0,1/4) and ++(0,-1/4) .. (0,3/2)
arc (90:0:3/8 and 1) arc (360:270:3/8 and 1/2);
}
\pgfmathsetseed{99}%
\draw [crayon=black!80] (dot-1) \foreach \l in {1,...,\k}{ to [sketch] (dot-\l) };
\end{tikzpicture}%
\end{minipage}}
\end{document}
通过使用动画功能瘸子可以pdf
转换为gif
:
最后,这是一个陀螺:
\documentclass[tikz,border=0.125cm]{standalone}
\newcount\TeXXeTstate% <- Why?
\usepackage{cjhebrew}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\newcount\tikzjointhedotsnumber
\pgfdeclaredecoration{join the dots}{initial}{%
\state{initial}[width=0pt, next state=do dots, persistent precomputation={\global\tikzjointhedotsnumber=1}]{}
%
\state{do dots}[width=\pgfdecoratedinputsegmentlength, persistent postcomputation={\global\advance\tikzjointhedotsnumber by1}]{%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
}
%
\state{final}{%
% Is the last point the same as the first?
\pgfpointdiff{\pgfpointdecoratedpathlast}{\pgfpointdecoratedpathfirst}%
\pgfmathveclen{\the\pgf@x}{\the\pgf@y}%
\ifdim\pgfmathresult pt=0pt\relax%
\global\advance\tikzjointhedotsnumber by-1\relax
\else
\pgftransformshift{\pgfpointdecoratedpathlast}%
\pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
\fi
% Ok, now we do everything. Draw the dots and place the numbers.
%
\c@pgf@counta=\tikzjointhedotsnumber%
\c@pgf@countb=2\relax%
\edef\lastdot{\the\tikzjointhedotsnumber}%
\def\nextdot{2}%
\pgftransformreset%
\pgfmathloop%
\ifnum\pgfmathcounter>\tikzjointhedotsnumber
\else%
% Draw the dot.
\edef\tmp{\the\tikzjointhedotsnumber}%
\tikzjointhedotsnumber=\pgfmathcounter\relax%
\path [shift={(@dot-\pgfmathcounter)}, every dot/.try, dot \pgfmathcounter/.try];
\tikzjointhedotsnumber=\tmp%
%
% Calculate the dot number node anchor
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@counta}{center}}%
\pgf@xc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@xc%
\advance\pgf@xc by360pt\relax%
\fi%
\pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@countb}{center}}%
\pgf@yc=\pgfmathresult pt\relax%
\ifdim0pt>\pgf@yc%
\advance\pgf@yc by360pt\relax%
\fi%
\ifdim\pgf@xc>\pgf@yc%
\pgf@x=360pt\relax%
\else%
\pgf@x=0pt\relax%
\fi%
\advance\pgf@x by-\pgf@xc%
\advance\pgf@x by\pgf@yc%
\divide\pgf@x by2\relax%
\advance\pgf@x by\pgf@xc%
\advance\pgf@x by180pt\relax%
\edef\dotnumberanchor{\the\pgf@x}%
\node [anchor=\dotnumberanchor, every dot number/.try, dot number \pgfmathcounter/.try]
at (@dot-\pgfmathcounter)
{\tikzjointhedotsnumber=\pgfmathcounter\relax\tikzjointhedotstypesetnumber{\tikzjointhedotsnumber}};
\c@pgf@counta=\pgfmathcounter\relax%
\advance\c@pgf@countb by1\relax%
\ifnum\c@pgf@countb>\tikzjointhedotsnumber%
\c@pgf@countb=1\relax%
\fi%
\repeatpgfmathloop%
}
}
% Command for typesetting dot number
% #1 - a count register holding the current dot number
%
\def\tikzjointhedotstypesetnumber#1{\the#1}
\makeatletter
% Keys for setting dot number styles
\tikzset{%
syle dot number range/.code args={#1 to #2 with #3}{%
\c@pgf@counta=#1
\pgfmathloop
\ifnum\c@pgf@counta>#2\relax%
\else%
\tikzset{dot number \the\c@pgf@counta/.style={#3}}%
\advance\c@pgf@counta by1
\repeatpgfmathloop%
},
style dot number list/.code args={#1 with #2}{%
\pgfutil@for\tmp:=#1\do{%
\tikzset{dot number \tmp/.style={#2}}%
}%
}
}
\makeatother
\tikzset{%
% Executed for every dot
every dot/.style={fill=black,
insert path={ circle [radius=.75mm] coordinate [alias=dot-last] (dot-\the\tikzjointhedotsnumber) }
},
% Executed for every dot number
every dot number/.style={
font=\footnotesize\sf,
anchor=\pgfdecoratedangle-90
},
join the dots/.style={
decoration=join the dots, decorate
},
lines/.style={
ultra thick,
line join=round,
line cap=round
},
style dot number list={15,16,17 with anchor=0},
}
\def\tikzjointhedotstypesetnumber#1{%
\textcjheb{\ifcase#1\or'\or b\or g\or d\or h\or w\or z\or.h\or.t\or y\or k|%
\or l\or m|\or n|\or s\or `\or p|\or.s|\or q\or r\or/s\or t\else?\fi}}
\begin{document}
\begin{tikzpicture}[x=(-40:0.5cm), y=(195:0.5cm), z=(75:0.5cm)]
\draw [lines] (1*cos 45,-1*sin 45,7) -- (1*cos 45,-1*sin 45,3) arc (-45:135:1) -- (-1*cos 45,1*sin 45,5.25);
\path[postaction=join the dots]
(1*cos 45,-1*sin 45,5.25) -- (3,-3, 3) -- (3,0,3) -- (3,3,3)
-- (3,3,1) -- (3,3,-1) -- (3,3,-3) -- (3,0,-3) -- (3,-3,-3)
-- (2,-2,-5) -- (1,-1,-7) -- (0,0,-9)
-- (-1,1,-7) -- (-2,2,-5) -- (-3,3,-3)
-- (-3,3,0) -- (-3,3,3) -- (-1*cos 45,1*sin 45,5.25) -- (-1*cos 45,1*sin 45,7)
-- (-1*cos 45,1*sin 45,9) -- (1*cos 45,-1*sin 45,9) -- (1*cos 45,-1*sin 45,7);
\node [yslant=-cos 40, scale=8, text=blue!50!purple] at (0,3,0) {\textcjheb{h}};
\node [yslant=cos 75, scale=8, text=red!50!orange] at (3,0,0) {\textcjheb{n|}};
\draw [lines]
(dot-4) -- (dot-17)
(dot-2) -- (dot-9)
(dot-7) -- (dot-15);
\end{tikzpicture}
\end{document}