How to draw a coffee cup

Topologists need to explain that coffee cups are homeomorphic to donuts. There are nice ways to draw donuts. So far, my best attempt is

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\shade[left color=gray!10, right color=gray!80] (-2,0) arc (180:540:2cm and 1cm);
\fill[top color=gray!50,bottom color=gray!80] (1.8,-.45) arc (135:225:.35cm) arc (45:-150:.35cm) arc (90:270:.25cm) arc (-90:45:.85cm) -- cycle;
\end{tikzpicture}
\end{document}


• Drawing donuts is relatively easy. Hence it only remains to find homeomorphism from a donut onto a cup. ;-) Nov 15, 2013 at 18:40
• Donut.........? Nov 15, 2013 at 19:04
• I don't see the difference between this and the question that cmhughes linked to so I'm going to vote to close as a duplicate. Nov 15, 2013 at 20:28
• @AndrewStacey Oh, no! The question is still an open problem. After closing it will not be homeomorphic to the present version. Nov 15, 2013 at 20:46
• For reasons unknown, this question makes me hungry. :) Nov 15, 2013 at 21:47

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}

% Saucer
\begin{scope}[shift={(0,-1)}]
(0,0) ++(180:1.25) arc (180:360:5/4 and 5/8+1/16);
\end{scope}

% Handle
\begin{scope}[shift=(10:7/8), rotate=-30, yslant=1/2, xslant=-1/8]
(0,0) arc (130:-100:3/8 and 1/2) -- ++(0,1/4) arc (-100:130:1/8 and 1/4) -- cycle;
(0,0) arc (130:-100:3/8 and 1/2) -- ++(0,1/32) arc (-100:130:1/4 and 1/3) -- cycle;
\end{scope}

% Cup
(-1,0) arc (180:360:1 and 5/4);
\shade [bottom color=gray, top color=gray!30, opacity=1/2]
(-1,0) arc (180:360:1 and 5/4);
\shade [bottom color=gray, top color=gray!10, opacity=1/2]

% Coffee
\begin{scope}
\fill [brown!25!black]
\end{scope}

\end{tikzpicture}

\end{document}


And clearly I've given up on doing any "proper" work today:

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\foreach \c [count=\i from 0] in {white,gray,red!75!black,blue!25, purple,orange}{

\tikzset{xshift={mod(\i,2)*3cm}, yshift=-floor(\i/2)*3cm}
\colorlet{cup}{\c}

% Saucer
\begin{scope}[shift={(0,-1-1/16)}]
\fill [cup, postaction={left color=black, right color=white, opacity=1/3}]
(0,0) ++(180:5/4) arc (180:360:5/4 and 5/8+1/16);
\fill [cup, postaction={left color=black!50, right color=white, opacity=1/3}]
\fill [cup, postaction={left color=white, right color=black, opacity=1/3}]
\fill [cup, postaction={left color=black, right color=white, opacity=1/3}]
\end{scope}

% Handle
\begin{scope}[shift=(10:7/8), rotate=-30, yslant=1/2, xslant=-1/8]
\fill [cup, postaction={top color=black, bottom color=white, opacity=1/3}]
(0,0) arc (130:-100:3/8 and 1/2) -- ++(0,1/4) arc (-100:130:1/8 and 1/4) -- cycle;
\fill [cup, postaction={top color=white, bottom color=black, opacity=1/3}]
(0,0) arc (130:-100:3/8 and 1/2) -- ++(0,1/32) arc (-100:130:1/4 and 1/3) -- cycle;
\end{scope}

% Cup
\fill [cup, postaction={left color=black, right color=white, opacity=1/3/2},
postaction={bottom color=black, top color=white, opacity=1/3/2}]
(-1,0) arc (180:360:1 and 5/4);
\fill [cup, postaction={left color=white, right color=black, opacity=1/3}]
\fill [cup, postaction={left color=black, right color=white, opacity=1/3/2},
postaction={bottom color=black, top color=white, opacity=1/3/2}]

% Coffee
\begin{scope}
\fill [brown!25!black]
\end{scope}
}
\end{tikzpicture}

\end{document}


• I particularly like the handle which is way superior to the other cups found on this page!
– user4686
Nov 17, 2013 at 21:36
• I want to see how the handle ends are fused to the cup body. Nov 18, 2013 at 14:10
• Very nice! I added your example to the TeXample TikZ Gallery. We can learn much from seeing how it's done in TikZ, even if there may be cliparts available somewhere else. Feb 3, 2014 at 14:52

In my opinion, it's really not worth it re-inventing the wheel when there's a bounty of coffee cups already out there:

All of the above images are open-source and can be opened/edited in Inkscape. Furthermore, if needed, it can be exported as-is in a variety of vectorized formats (if not downloaded in PDF from the source), or exported to TikZ using inkscape2tikz (never tried it though).

• I could be worth when you want to compute and show transitions between coffee cup and donuts.
– math
Nov 21, 2013 at 7:51

How about a cut that actually transforms into a donut (more or less smoothely)?

Code

\documentclass[tikz, border=2mm]{standalone}

\begin{document}

\foreach \x in {0,...,10}
{   \begin{tikzpicture}
\shade[left color=gray!80, right color=gray!30] (-2,0-\x*0.04) -- (-2,-4+\x*0.04) arc (180:360:2 and 0.5) -- (2,0-\x*0.04) arc (360:180:2 and 0.5);
\shade[left color=gray!60, right color=gray!20,even odd rule] (0,0-\x*0.04) circle (2 and 0.5) (0,0-\x*0.04) circle (1.8+\x*0.02 and 0.45+\x*0.005);
\shade[left color=gray!30, right color=gray!80] (0,0-\x*0.04) circle (1.8+\x*0.02 and 0.45+\x*0.005);
\begin{scope}
\clip (2,-0.4) arc (90:270:0.05-\x*0.005 and 0.2) arc (90:-90:0.6 and 1.2) arc (90:270:0.05-\x*0.005 and 0.2) arc (-90:90:0.8 and 1.6);
\fill[inner color=white, outer color=gray!60] (2,-2) circle (0.8 and 1.6);
\end{scope}
\draw (-2.1,-4.6) rectangle (2.9,0.6);
\end{tikzpicture}
}

\foreach \x in {0,...,10}
{   \begin{tikzpicture}
\shade[left color=gray!80, right color=gray!30] (-2+\x*0.36,-0.4) -- (-2+\x*0.36,-3.6) arc (180:360:2-\x*0.18 and 0.5-\x*0.05) -- (2,-0.4) arc (360:180:2-\x*0.18 and 0.5-\x*0.05);
\shade[left color=gray!30, right color=gray!80] (0+\x*0.18,-0.4) circle (2-\x*0.18 and 0.5-\x*0.05);
\begin{scope}
\clip (2,-0.4) -- ++(0,-0.4) arc (90:-90:0.6 and 1.2) -- ++(0,-0.4) arc (-90:90:0.8 and 1.6);
\fill[inner color=white, outer color=gray!60] (2,-2) circle (0.8 and 1.6);
\end{scope}
\draw (-2.1,-4.6) rectangle (2.9,0.6);
\end{tikzpicture}
}

\foreach \x in {0,...,10}
{   \begin{tikzpicture}
\begin{scope}
\clip (2,-0.4) -- ++(-0.4+\x*0.04,0) arc (90:270:\x*0.08 and 1.6) -| ++(0.4-\x*0.04,0.4) arc (270:90:\x*0.06 and 1.2);
\fill[inner color=white, outer color=gray!60] (1.2,-0.4) rectangle ++(1.6,-3.2);
\end{scope}
\begin{scope}
\clip (2,-0.4) -- ++(0,-0.4) arc (90:-90:0.6 and 1.2) -- ++(0,-0.4) arc (-90:90:0.8 and 1.6);
\fill[inner color=white, outer color=gray!60] (2,-2) circle (0.8 and 1.6);
\end{scope}
\draw (-2.1,-4.6) rectangle (2.9,0.6);
\end{tikzpicture}
}

\foreach \x in {0,...,10}
{   \begin{tikzpicture}
\fill[inner color=white, outer color=gray!60,even odd rule] (2-\x*0.16,-2) circle (0.8+\x*0.16 and 1.6) (2-\x*0.16,-2) circle (0.6+\x*0.09 and 1.2-\x*0.02);
\draw (-2.1,-4.6) rectangle (2.9,0.6);
\end{tikzpicture}
}

\end{document}


Output

• Nice, although it is not a homeomorphism. Nov 16, 2013 at 20:39

This is really expanding on Werner's answer.

\documentclass[tikz, border=4pt]{standalone}

\begin{document}

\definecolor{cC6C5C4}{RGB}{198,197,196}
\definecolor{c9B9999}{RGB}{155,153,153}
\definecolor{cEBEBEB}{RGB}{235,235,235}
\definecolor{cE2E1E1}{RGB}{226,225,225}
\definecolor{cC37660}{RGB}{195,118,96}

\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
\path[fill=cC6C5C4] (434.7610,355.3470) .. controls (434.8330,355.1840) and
(434.9160,355.0280) .. (435.0060,354.8760) .. controls (430.1610,355.7890) and
(419.1950,356.2480) .. (419.1950,356.2480) .. controls (419.1950,356.2480) and
(359.8720,367.7830) .. (359.0480,369.7050) .. controls (358.2240,371.6270) and
(362.8930,376.8460) .. (369.7590,379.0430) .. controls (371.7360,379.6760) and
(375.8590,381.0100) .. (381.4600,382.1710) .. controls (382.2580,381.3470) and
(383.4360,380.8590) .. (385.0000,381.0010) .. controls (393.6770,381.7930) and
(402.7990,381.9730) .. (411.3610,380.1380) .. controls (415.4250,379.2670) and
(419.5480,378.7220) .. (423.6640,378.1630) .. controls (423.9010,377.5740) and
(424.2730,377.0450) .. (424.7990,376.6330) .. controls (426.7260,375.1190) and
(429.2370,374.1350) .. (430.4720,371.9760) .. controls (431.6770,369.8710) and
(432.7150,367.6620) .. (433.9490,365.5770) .. controls (433.9980,365.4950) and
(434.0510,365.4230) .. (434.1000,365.3420) .. controls (428.4430,365.0610) and
(428.7070,355.9080) .. (434.7610,355.3470) -- cycle;
\path[fill=c9B9999] (439.8940,313.0410) .. controls (439.4410,316.1700) and
(437.8830,327.5880) .. (435.6440,338.7910) .. controls (438.5020,338.1150) and
(442.3000,335.1050) .. (444.6440,329.0410) .. controls (448.8940,318.0410) and
(446.3940,310.2910) .. (444.8940,311.2910) .. controls (444.1440,311.7910) and
(441.8320,311.8520) .. (439.8940,313.0410) -- (439.8940,313.0410) --
cycle(394.1430,280.5400) .. controls (402.8930,281.0400) and
(404.8790,280.1140) .. (424.6430,284.2900) .. controls (442.3930,288.0400) and
(441.8930,297.0400) .. (441.8930,297.0400) -- (441.8930,299.7900) .. controls
(444.8290,298.8320) and (448.2350,299.1590) .. (450.1430,299.5400) .. controls
(452.6430,300.0400) and (463.1430,308.7910) .. (457.3930,325.7910) .. controls
(451.6430,342.7910) and (444.1430,349.7910) .. (436.6430,354.7910) .. controls
(434.3390,356.3260) and (432.5070,357.5780) .. (431.0750,358.5780) .. controls
(430.2000,362.6210) and (429.5680,365.3080) .. (429.3930,365.5410) .. controls
(428.6430,366.5410) and (424.1430,375.0410) .. (396.8930,376.0410) .. controls
(369.6430,377.0410) and (358.8930,371.0410) .. (355.3930,366.7910) .. controls
(351.8930,362.5410) and (340.6430,302.0400) .. (340.8930,297.0400) .. controls
(341.1430,292.0400) and (347.8930,287.0400) .. (358.3930,283.7900) .. controls
(367.5340,280.9610) and (385.3930,280.0400) .. (394.1430,280.5400) --
(394.1430,280.5400) -- cycle;
\path[fill=cEBEBEB] (370.3090,309.2830) .. controls (353.7600,307.1420) and
(346.5490,302.1870) .. (343.4390,297.9180) .. controls (342.9600,291.7080) and
(353.7490,286.0490) .. (366.8760,284.2900) .. controls (369.4630,283.9430) and
(374.3920,283.3960) .. (374.3920,283.3960) -- (388.0050,282.5240) .. controls
(388.0050,282.5240) and (393.1330,282.4410) .. (394.4630,282.5320) .. controls
(395.7930,282.6230) and (399.6760,282.7570) .. (399.6760,282.7570) .. controls
(399.6760,282.7570) and (415.3420,284.5460) .. (416.7500,284.7780) .. controls
(431.0540,287.1390) and (439.0400,290.5350) .. (440.0560,297.4870) --
(439.8670,298.8380) .. controls (437.9280,301.0720) and (435.6770,303.1010) ..
(433.2030,304.3380) .. controls (424.9630,308.4590) and (405.4790,313.8300) ..
(370.3090,309.2830) -- (370.3090,309.2830) -- cycle;
\path[fill=cC6C5C4] (343.4380,297.9180) .. controls (346.5480,302.1870) and
(353.7590,307.1420) .. (370.3080,309.2830) .. controls (405.4780,313.8300) and
(424.9620,308.4590) .. (433.2020,304.3390) .. controls (435.6760,303.1020) and
(437.9270,301.0730) .. (439.8660,298.8390) .. controls (438.5560,308.0820) and
(430.7960,361.7480) .. (426.6110,365.5860) .. controls (420.0190,371.6270) and
(409.3080,374.1000) .. (388.9840,374.3730) .. controls (368.6600,374.6480) and
(364.1210,370.3400) .. (357.4000,365.8590) .. controls (354.1050,363.6620) and
(345.8640,316.5660) .. (343.4670,298.1920) -- (343.4380,297.9180) --
(343.4380,297.9180) -- cycle;
\path[fill=cC6C5C4,even odd rule] (429.2200,290.6070) .. controls
(425.8610,289.3550) and (417.8990,287.2900) .. (413.6920,286.8720) .. controls
(411.6200,286.6650) and (402.2160,285.3330) .. (391.4220,285.2500) .. controls
(380.3000,285.1650) and (367.7140,286.3620) .. (361.1080,288.4100) .. controls
(354.6080,290.4250) and (344.3550,294.4520) .. (347.2380,298.4350) .. controls
(347.6940,299.0640) and (348.6340,299.8310) .. (350.0340,300.6580) .. controls
(353.0400,299.0340) and (358.4560,296.6780) .. (366.6230,295.0120) .. controls
(367.1020,295.5020) and (367.7790,295.8270) .. (368.6660,295.8350) .. controls
(373.8160,295.8780) and (380.9310,296.8800) .. (385.7810,294.1870) .. controls
(386.0070,294.2790) and (386.2510,294.3550) .. (386.5350,294.3950) .. controls
(389.6370,294.8240) and (392.6640,295.5840) .. (395.7740,295.9720) .. controls
(399.0870,296.3860) and (401.5770,294.6470) .. (404.7350,294.3600) .. controls
(405.3010,294.3080) and (405.8600,294.2900) .. (406.4160,294.2860) .. controls
(408.3660,294.8480) and (410.2280,295.0640) .. (412.0880,294.9370) .. controls
(416.2760,295.8640) and (420.3010,297.5530) .. (424.5350,298.5620) .. controls
(425.5620,298.8070) and (426.4580,298.5410) .. (427.1180,298.0080) .. controls
(427.1320,298.0130) and (427.1450,298.0190) .. (427.1590,298.0240) .. controls
(429.4520,298.9060) and (431.3660,299.8630) .. (432.8070,300.6700) .. controls
(438.7790,296.6600) and (434.2660,292.4890) .. (429.2200,290.6070) -- cycle;
\path[fill=cC6C5C4] (426.8860,307.9100) .. controls (426.8860,307.9100) and
(440.7690,301.3120) .. (446.9350,301.0430) .. controls (453.2520,300.7690) and
(457.3720,309.6950) .. (456.5470,318.4840) .. controls (455.8180,326.2610) and
(451.3290,340.0430) .. (443.0900,347.4590) .. controls (436.6800,353.2290) and
(422.2170,361.1910) .. (422.2170,361.1910) -- (426.6120,342.7890) .. controls
(426.6120,342.7890) and (437.8290,343.2930) .. (442.2660,336.7480) .. controls
(453.2520,320.5430) and (447.7590,311.4800) .. (446.3860,309.8320) .. controls
(445.0120,308.1840) and (427.4350,316.1480) .. (427.4350,316.1480) --
(426.8860,307.9100) -- (426.8860,307.9100) -- cycle;
\path[fill=cEBEBEB] (441.5790,303.1040) .. controls (445.8360,301.4560) and
(447.7590,301.0440) .. (450.5050,302.6920) .. controls (453.2520,304.3400) and
(454.9000,310.2450) .. (454.9000,310.2450) .. controls (454.9000,310.2450) and
(451.7420,305.1640) .. (449.1320,304.3400) .. controls (446.5220,303.5160) and
(437.3220,304.7510) .. (441.5790,303.1040) -- (441.5790,303.1040) -- cycle;
\path[fill=cEBEBEB,even odd rule] (434.4380,343.6130) .. controls
(437.7340,341.9650) and (440.8920,339.9060) .. (443.5010,337.1600) .. controls
(446.1100,334.4120) and (447.3460,329.3320) .. (447.3460,329.3320) .. controls
(447.3460,329.3320) and (443.9130,340.4550) .. (440.4800,343.6130) .. controls
(437.0470,346.7710) and (434.4380,349.6560) .. (434.0260,350.6170) .. controls
(433.6140,351.5780) and (431.1430,345.2620) .. (434.4380,343.6130) --
(434.4380,343.6130) -- cycle;
\path[fill=cE2E1E1] (374.1530,313.9510) .. controls (376.3500,313.9510) and
(384.8640,313.6780) .. (393.1040,314.2260) .. controls (401.3440,314.7740) and
(416.7240,312.0290) .. (416.7240,312.0290) .. controls (416.7240,312.0290) and
(410.6820,334.0000) .. (410.6820,348.2830) .. controls (410.6820,362.5640) and
(403.8160,371.6270) .. (401.6190,371.6270) .. controls (399.4220,371.6270) and
(389.8090,374.1000) .. (387.6120,370.8030) .. controls (385.4150,367.5080) and
(376.0770,345.5350) .. (375.5280,339.4940) .. controls (374.9770,333.4510) and
(371.9560,313.9510) .. (374.1530,313.9510) -- (374.1530,313.9510) -- cycle;
\path[fill=c9B9999] (359.3230,374.9240) .. controls (370.5830,380.4160) and
(404.2280,382.7500) .. (423.1780,375.1970) .. controls (433.2290,371.1910) and
(431.4170,363.1130) .. (431.4170,363.1130) .. controls (431.4170,363.1130) and
(434.2680,364.6930) .. (434.8510,367.0950) .. controls (435.9500,371.6260) and
(426.1630,379.2140) .. (415.6250,380.9640) .. controls (367.6990,388.9300) and
(348.0620,369.4300) .. (359.3230,374.9240) -- (359.3230,374.9240) -- cycle;
\path[fill=cC37660] (350.0350,300.6580) .. controls (353.2680,298.9110) and
(359.7100,295.7890) .. (368.5220,294.6450) .. controls (377.3340,293.5010) and
(381.6000,293.1490) .. (384.0970,293.0750) .. controls (386.5940,293.0010) and
(388.1780,293.3240) .. (392.0060,293.0790) .. controls (395.8340,292.8340) and
(410.6660,293.9330) .. (414.4520,294.5400) .. controls (418.2380,295.1470) and
(423.9010,296.7690) .. (427.1610,298.0220) .. controls (429.4540,298.9040) and
(431.3680,299.8610) .. (432.8090,300.6680) .. controls (429.1930,303.0950) and
(421.7300,305.4620) .. (408.2100,307.2230) .. controls (378.0340,311.1540) and
(357.4950,305.0590) .. (350.0350,300.6580) -- (350.0350,300.6580) -- cycle;

\end{tikzpicture}

\end{document}


I started with a free clip art coffee cup, edited it until I was happy with it (I felt the steam and saucer distracted from its topological properties), and used the inkscape plugin inkscape2tikz. The resulting code is pretty indecipherable, but you get a nice coffee cup!

Also: I think I might have a hardcore procrastination problem.

• From the looks of your blog I'd say it is a hardcore enthusiasm problem :)
– flip
Nov 16, 2013 at 23:13

Just a little addition to make the border of the cup thicker and improving the lighting:

\usetikzlibrary{shadings}
\begin{tikzpicture}