tikz add tag
samcarter
How to draw a doughnut[^1] with all the delicious toppings?


[^1]: In case anyone is wondering why a doughnut and not, say, broccoli, have a look at https://www.bbc.co.uk/ideas/videos/the-science-behind-why-doughnuts-are-so-hard-to-re/p08l9dzq
Top Answer
samcarter
With the following code, you can create your own doughnut just as you like it.

The plain doughnut  is drawn with the `\doughnut` macro. As decoration, `icing`, `garnish` and `sprinkles` can be added in whatever colour you fancy. By default the sprinkles are multi-coloured.


```
\documentclass{standalone}

\usepackage{tikz}

\newif\ifsprinkles
\newif\ificing
\newif\ifgarnish
\def\multistring{multi}

\tikzset{
  /doughnut/.search also={/tikz,/pgf},
  /doughnut/.cd,
  sprinkles/.code      = \sprinklestrue
                         \def\sprinklescol{#1},
  sprinkles/.default   = multi,  
  icing/.code          = \icingtrue
                         \def\icing{#1},
  icing/.default       = violet, 
  garnish/.code        = \garnishtrue
                         \def\garnishcol{#1},
  garnish/.default     = brown!50!black,     
}

\newcommand*{\doughnut}[1][]{%
  \begin{scope}%
    \tikzset{/doughnut/.cd,#1}%
    \fill[brown,even odd rule] (5.53,5.14) ellipse[x radius=0.83, y radius=0.56] (5.56,5.2) ellipse[x radius=0.2, y radius=0.06];
    \ificing
      \fill[\icing] (5.7998,5.2783) .. controls (5.7998,5.1847) and (5.6816,5.1324) .. (5.5553,5.1324) .. controls (5.4290,5.1324) and (5.3187,5.1847) .. (5.3187,5.2783) .. controls (5.3187,5.3720) and (5.4211,5.4163) .. (5.5474,5.4163) .. controls (5.6737,5.4163) and (5.7998,5.3720) .. (5.7998,5.2783) -- cycle(5.5277,5.7318) .. controls (5.0726,5.7318) and (4.7351,5.4797) .. (4.7036,5.2744) .. controls (4.7036,5.2112) and (4.7159,5.1409) .. (4.7683,5.0964) .. controls (4.9441,4.9470) and (4.9493,4.7321) .. (5.0238,4.6907) .. controls (5.0984,4.6493) and (5.0746,4.8945) .. (5.2069,4.8529) .. controls (5.5056,4.7591) and (5.4060,4.6356) .. (5.5198,4.6356) .. controls (5.6336,4.6356) and (5.4991,4.7678) .. (5.8485,4.8529) .. controls (6.0048,4.8910) and (6.0359,4.8070) .. (6.1105,4.8484) .. controls (6.1850,4.8898) and (6.1186,4.9082) .. (6.2871,5.0963) .. controls (6.3627,5.1808) and (6.3519,5.2112) .. (6.3519,5.2744) .. controls (6.2888,5.4797) and (5.9829,5.7318) .. (5.5277,5.7318) -- cycle;
    \fi
    \ifgarnish
      \draw[\garnishcol, line width=0.5] (4.8140,5.4006) .. controls (4.7837,5.3328) and (4.7784,5.2541) .. (4.7994,5.1829) .. controls (4.8033,5.1698) and (4.8082,5.1565) .. (4.8173,5.1462) .. controls (4.8218,5.1411) and (4.8273,5.1368) .. (4.8336,5.1341) .. controls (4.8399,5.1314) and (4.8470,5.1304) .. (4.8538,5.1317) .. controls (4.8601,5.1330) and (4.8659,5.1363) .. (4.8707,5.1406) .. controls (4.8754,5.1450) and (4.8792,5.1504) .. (4.8820,5.1562) .. controls (4.8877,5.1678) and (4.8900,5.1807) .. (4.8932,5.1933) .. controls (4.9057,5.2426) and (4.9320,5.2871) .. (4.9579,5.3309) .. controls (4.9838,5.3747) and (5.0099,5.4194) .. (5.0220,5.4689) .. controls (5.0254,5.4827) and (5.0278,5.4973) .. (5.0354,5.5093) .. controls (5.0392,5.5154) and (5.0444,5.5207) .. (5.0507,5.5240) .. controls (5.0571,5.5273) and (5.0647,5.5284) .. (5.0715,5.5263) .. controls (5.0775,5.5245) and (5.0826,5.5204) .. (5.0861,5.5152) .. controls (5.0896,5.5100) and (5.0914,5.5038) .. (5.0920,5.4976) .. controls (5.0931,5.4851) and (5.0891,5.4728) .. (5.0848,5.4611) .. controls (5.0504,5.3671) and (4.9924,5.2828) .. (4.9613,5.1877) .. controls (4.9552,5.1690) and (4.9501,5.1491) .. (4.9535,5.1298) .. controls (4.9552,5.1201) and (4.9591,5.1107) .. (4.9655,5.1032) .. controls (4.9718,5.0957) and (4.9808,5.0902) .. (4.9905,5.0887) .. controls (4.9970,5.0877) and (5.0037,5.0885) .. (5.0100,5.0906) .. controls (5.0163,5.0926) and (5.0221,5.0959) .. (5.0274,5.0998) .. controls (5.0380,5.1077) and (5.0465,5.1179) .. (5.0555,5.1276) .. controls (5.0777,5.1513) and (5.1032,5.1719) .. (5.1245,5.1964) .. controls (5.1583,5.2352) and (5.1805,5.2825) .. (5.2030,5.3288) .. controls (5.2246,5.3731) and (5.2470,5.4172) .. (5.2657,5.4628) .. controls (5.2803,5.4987) and (5.2927,5.5356) .. (5.3117,5.5694) .. controls (5.3306,5.6031) and (5.3571,5.6341) .. (5.3922,5.6504) .. controls (5.4024,5.6551) and (5.4133,5.6586) .. (5.4245,5.6595) .. controls (5.4357,5.6604) and (5.4473,5.6587) .. (5.4573,5.6536) .. controls (5.4681,5.6481) and (5.4769,5.6388) .. (5.4826,5.6281) .. controls (5.4883,5.6174) and (5.4910,5.6052) .. (5.4916,5.5930) .. controls (5.4925,5.5705) and (5.4858,5.5482) .. (5.4765,5.5277) .. controls (5.4611,5.4942) and (5.4386,5.4645) .. (5.4155,5.4357) .. controls (5.3807,5.3923) and (5.3442,5.3502) .. (5.3102,5.3062) .. controls (5.2571,5.2374) and (5.2086,5.1599) .. (5.2015,5.0733) .. controls (5.2006,5.0620) and (5.2004,5.0505) .. (5.2027,5.0394) .. controls (5.2050,5.0283) and (5.2100,5.0175) .. (5.2183,5.0098) .. controls (5.2283,5.0003) and (5.2426,4.9960) .. (5.2564,4.9967) .. controls (5.2702,4.9974) and (5.2835,5.0029) .. (5.2949,5.0108) .. controls (5.3176,5.0265) and (5.3324,5.0509) .. (5.3486,5.0733) .. controls (5.3670,5.0988) and (5.3879,5.1224) .. (5.4110,5.1437) -- (5.4116,5.1490) -- (5.4111,5.1539)(5.5609,5.4274) .. controls (5.5976,5.4672) and (5.6267,5.5140) .. (5.6461,5.5645) .. controls (5.6534,5.5833) and (5.6595,5.6031) .. (5.6724,5.6185) .. controls (5.6789,5.6263) and (5.6870,5.6328) .. (5.6964,5.6363) .. controls (5.7059,5.6398) and (5.7166,5.6402) .. (5.7259,5.6364) .. controls (5.7355,5.6324) and (5.7430,5.6243) .. (5.7476,5.6150) .. controls (5.7523,5.6057) and (5.7544,5.5953) .. (5.7555,5.5850) .. controls (5.7593,5.5512) and (5.7533,5.5163) .. (5.7384,5.4856) .. controls (5.7235,5.4550) and (5.6998,5.4287) .. (5.6708,5.4108)(5.5080,5.1246) .. controls (5.4881,5.1100) and (5.4752,5.0863) .. (5.4737,5.0617) .. controls (5.4722,5.0370) and (5.4822,5.0119) .. (5.5002,4.9951) .. controls (5.5166,4.9798) and (5.5389,4.9715) .. (5.5613,4.9707) .. controls (5.5848,4.9699) and (5.6081,4.9769) .. (5.6287,4.9881) .. controls (5.6493,4.9994) and (5.6674,5.0146) .. (5.6843,5.0310) .. controls (5.7434,5.0883) and (5.7876,5.1598) .. (5.8192,5.2359) .. controls (5.8385,5.2825) and (5.8532,5.3309) .. (5.8648,5.3800) .. controls (5.8717,5.4096) and (5.8776,5.4399) .. (5.8909,5.4674) .. controls (5.8975,5.4811) and (5.9060,5.4940) .. (5.9168,5.5048) .. controls (5.9275,5.5156) and (5.9406,5.5242) .. (5.9552,5.5288) .. controls (5.9659,5.5321) and (5.9773,5.5332) .. (5.9884,5.5315) .. controls (5.9995,5.5298) and (6.0102,5.5251) .. (6.0187,5.5178) .. controls (6.0294,5.5086) and (6.0363,5.4955) .. (6.0393,5.4818) .. controls (6.0424,5.4680) and (6.0418,5.4536) .. (6.0392,5.4398) .. controls (6.0339,5.4121) and (6.0207,5.3866) .. (6.0123,5.3597) .. controls (6.0010,5.3235) and (5.9984,5.2852) .. (5.9928,5.2477) .. controls (5.9873,5.2101) and (5.9781,5.1719) .. (5.9557,5.1413) .. controls (5.9449,5.1264) and (5.9312,5.1137) .. (5.9210,5.0984) .. controls (5.9159,5.0908) and (5.9117,5.0824) .. (5.9094,5.0735) .. controls (5.9072,5.0646) and (5.9070,5.0550) .. (5.9098,5.0463) .. controls (5.9122,5.0387) and (5.9168,5.0318) .. (5.9227,5.0264) .. controls (5.9286,5.0210) and (5.9357,5.0171) .. (5.9433,5.0144) .. controls (5.9569,5.0097) and (5.9719,5.0094) .. (5.9860,5.0127) .. controls (6.0001,5.0160) and (6.0132,5.0227) .. (6.0248,5.0315) .. controls (6.0478,5.0489) and (6.0641,5.0737) .. (6.0785,5.0987) .. controls (6.0944,5.1265) and (6.1086,5.1551) .. (6.1238,5.1833) .. controls (6.1496,5.2311) and (6.1784,5.2774) .. (6.2099,5.3217);
    \fi
    \ifsprinkles
      \begin{scope}
        \clip (5.7998,5.2783) .. controls (5.7998,5.1847) and (5.6816,5.1324) .. (5.5553,5.1324) .. controls (5.4290,5.1324) and (5.3187,5.1847) .. (5.3187,5.2783) .. controls (5.3187,5.3720) and (5.4211,5.4163) .. (5.5474,5.4163) .. controls (5.6737,5.4163) and (5.7998,5.3720) .. (5.7998,5.2783) -- cycle(5.5277,5.7318) .. controls (5.0726,5.7318) and (4.7351,5.4797) .. (4.7036,5.2744) .. controls (4.7036,5.2112) and (4.7159,5.1409) .. (4.7683,5.0964) .. controls (4.9441,4.9470) and (4.9493,4.7321) .. (5.0238,4.6907) .. controls (5.0984,4.6493) and (5.0746,4.8945) .. (5.2069,4.8529) .. controls (5.5056,4.7591) and (5.4060,4.6356) .. (5.5198,4.6356) .. controls (5.6336,4.6356) and (5.4991,4.7678) .. (5.8485,4.8529) .. controls (6.0048,4.8910) and (6.0359,4.8070) .. (6.1105,4.8484) .. controls (6.1850,4.8898) and (6.1186,4.9082) .. (6.2871,5.0963) .. controls (6.3627,5.1808) and (6.3519,5.2112) .. (6.3519,5.2744) .. controls (6.2888,5.4797) and (5.9829,5.7318) .. (5.5277,5.7318) -- cycle;
        \foreach \x in {1,...,400} {
          \ifx\sprinklescol\multistring
            \pgfmathsetmacro{\R}{rnd}%
            \pgfmathsetmacro{\G}{rnd}%
            \pgfmathsetmacro{\B}{rnd}%
            \definecolor{randomcol}{rgb}{\R,\G,\B}%
            \draw[randomcol] (rnd*2+4.5,rnd*1.3+4.5) -- ++(rnd*360:0.05);
          \else
            \draw[\sprinklescol] (rnd*2+4.5,rnd*1.3+4.5) -- ++(rnd*360:0.05);
          \fi
        }
      \end{scope}
    \fi
  \end{scope}%
}

\begin{document}
\begin{tikzpicture}
\doughnut
\end{tikzpicture}

\begin{tikzpicture}
\doughnut[icing]
\end{tikzpicture}

\begin{tikzpicture}
\doughnut[icing=orange!40!white,garnish]
\end{tikzpicture}

\begin{tikzpicture}
\doughnut[icing=brown!50!black,sprinkles=white]
\end{tikzpicture}

\begin{tikzpicture}
\doughnut[icing=violet!40!red!40!white,sprinkles]
\end{tikzpicture}
\end{document}
```

![doughnut](/image?hash=cbfb31db4c678d37fb9e5025f868c0b45dfcc30ff9efc6448ab2e06ff8325ee8)

(this code is also available as a small package at https://github.com/samcarter/tikzbits)
Answer #2
user 3.14159
Here is a doughnut for mathematicians and physicists, who have the strange habit of calling a doughnut a torus. It requires the [3dtools library](https://github.com/marmotghost/tikz-3dtools), which contains functions for some critical angles. This means that you can adjust the view and draw cycles that wrap around tori.
```
\documentclass[beamer,tikz,preview]{standalone}
\usetikzlibrary{3dtools,overlay-beamer-styles,shapes.arrows}
\tikzset{3d torus/.style n
args={2}{/utils/exec=\pgfmathsetmacro{\DDA}{int(sign(sin(thetacritA(#1,#2))-sin(\pgfkeysvalueof{/tikz/3d/theta})))}
  \pgfmathsetmacro{\DDB}{int(sign(sin(thetacritB(#1,#2))-sin(\pgfkeysvalueof{/tikz/3d/theta})))},
  insert path={
  plot[variable=\x,domain=1:359,smooth cycle,samples=71]
  ({torusx(\x,torusvcrit1(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 {torusy(\x,torusvcrit1(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 {torusz(\x,torusvcrit1(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)}) 
   \ifnum\DDA=1
	plot[variable=\x,domain=0:360,smooth cycle,samples=71]
  	({torusx(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusy(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusz(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)})    
   \else
   \ifnum\DDB=1	
	plot[variable=\x,domain={umaxA(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})}:{umaxB(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})},smooth,samples=71]
  	({torusx(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusy(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusz(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)})    --
	plot[variable=\x,domain={180+umaxA(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})}:{180+umaxB(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})},smooth,samples=71]
  	({torusx(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusy(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusz(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)})  -- cycle  
    \fi	
   \fi
  }},
  3d torus stretch/.style n args={2}{/utils/exec=\pgfmathsetmacro{\DDA}{int(sign(thetacritA(#1,#2)-\pgfkeysvalueof{/tikz/3d/theta}))},
  insert path={\ifnum\DDA=-1
   plot[variable=\x,domain={ucritA(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})}:{ucritB(#1,#2,\pgfkeysvalueof{/tikz/3d/theta})},smooth,samples=71]
  	({torusx(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusy(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)},
 	{torusz(\x,torusvcrit2(\x,\pgfkeysvalueof{/tikz/3d/theta}),#1,#2)}) 
  \fi 
}}}
\tikzset{declare function={%
thetacritA(\R,\r)=atan(sqrt(\R/\r-1));
thetacritB(\R,\r)=acos(\r/\R);
ucritA(\R,\r,\th)=180+(90/pi)*sqrt(abs(-(\R^2*pow(cot(\th),2))+4*pow(\r,2)/pow(sin(2*\th),2)))/\R; 
ucritB(\R,\r,\th)=540-ucritA(\R,\r,\th);
umaxA(\R,\r,\th)=asin(sqrt(abs(-pow(cot(\th),2)+4*pow(\r,2)/(pow((sin(2*\th)*\R),2)))));
umaxB(\R,\r,\th)=180-umaxA(\R,\r,\th);}}

\begin{document}
\begin{standaloneframe}%
%\frametitle{}
%\tdplotsetmaincoords{65}{0}
\begin{tikzpicture}[3d/install view={theta=65,phi=0},
	declare function={R=3;r=1;phicycle=310;delta=5;}]
\begin{scope}[local bounding box=torus]
 \pgfmathsetmacro{\rprime}{r}
 \begin{scope}[visible on=<3->]
  \pgfmathsetmacro{\umin}{360+torusvcrit1(phicycle,\pgfkeysvalueof{/tikz/3d/theta})}
  \pgfmathsetmacro{\umax}{torusvcrit2(phicycle,\pgfkeysvalueof{/tikz/3d/theta})}
  \fill[red] plot[smooth,variable=\x,domain=\umin:\umax,samples=31]   
	 ({torusx(phicycle,\x,R,\rprime)},{torusy(phicycle,\x,R,\rprime)},{torusz(phicycle,\x,R,\rprime)})
   -- plot[smooth,variable=\x,domain=\umax:\umin,samples=31]   
	 ({torusx(phicycle+delta,\x,R,\rprime)},{torusy(phicycle+delta,\x,R,\rprime)},{torusz(phicycle,\x,R,\rprime)})
   -- cycle;
 \end{scope}
% %torus
 \draw[thick,samples=71,fill=gray,fill opacity=0.7,even odd
	rule,3d torus={R}{r}] ;
 \draw[thick,samples=71,3d torus stretch={R}{r}];
% 
 \begin{scope}[visible on=<2->]
  \draw[blue,line width=1mm]
	  plot[smooth,variable=\x,domain=0:360,samples=61]   
	({R*cos(\x)},{R*sin(\x)},r);
 \end{scope}
 \begin{scope}[visible on=<3->]
  \pgfmathsetmacro{\umin}{torusvcrit2(phicycle,\pgfkeysvalueof{/tikz/3d/theta})}
  \pgfmathsetmacro{\umax}{torusvcrit1(phicycle,\pgfkeysvalueof{/tikz/3d/theta})}
  \fill[red] plot[smooth,variable=\x,domain=\umin:\umax,samples=31]   
	({torusx(phicycle,\x,R,\rprime)},{torusy(phicycle,\x,R,\rprime)},{torusz(phicycle,\x,R,\rprime)})
	-- plot[smooth,variable=\x,domain=\umax:\umin,samples=31]   
	({torusx(phicycle+delta,\x,R,\rprime)},{torusy(phicycle+delta,\x,R,\rprime)},{torusz(phicycle,\x,R,\rprime)})
  	-- cycle;
 \end{scope}
\end{scope}
\end{tikzpicture}%
\end{standaloneframe}
\end{document}
```
![ani.gif](/image?hash=b4d1780587882b4e5f9bff8b8160b3cd7f232a1d1ee246d8eb263117613e7a09)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.