# How to draw a mattress in TikZ?

I am trying to make a nice picture of the top view of a mattress in TikZ. I have made two attempts, one with wavy lines and one with a grid pattern:

\documentclass{article}
\usepackage{tikz}
\begin{document}

With wavy lines:

\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

\useasboundingbox (0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrcurve{6}
\pgfmathsetmacro\nrrow{12}

\pgfmathsetmacro\brcurve{\br/\nrcurve}
\pgfmathsetmacro\brcurvepart{\br/\nrcurve/4}
\pgfmathsetmacro\rowht{\ht/\nrrow}
\pgfmathsetmacro\curveampl{\rowht/5}

\newcommand\curvepart[2]{
(#1,#2+\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2-\curveampl)
(#1+\brcurvepart*2,#2-\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2+\curveampl)
}
\newcommand\curvepartneg[2]{
(#1,#2-\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2+\curveampl)
(#1+\brcurvepart*2,#2+\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2-\curveampl)
}

\draw[line width=1pt]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2} } };

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}

With grid pattern:

\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

\useasboundingbox (0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrlines{12}
\pgfmathsetmacro\linediff{\ht/12+\br/12}

\draw[line width=1pt]
\foreach \x in {2,...,\nrlines} {
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht)
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0)
};

\fill[white]    (0,-1) rectangle (-\ht,\ht+1)
(\br,-1) rectangle (\br+\ht,\ht+1);

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}
\end{document}


With the following result:

While these aren't terrible, in my opinion, they could certainly be improved. For example, they currently feel very flat (and not so soft), making the second look like a waffle.

How could I make these look more like the top view of a real life mattress?

Some context: I would like to use the mattress to explain symmetry groups, inspired by Group Theory in the Bedroom

• At first I thought "mattress" was a typo for "matrix" :) (+1, btw)! May 29, 2017 at 8:04
• You could use shading near the seams. This could be done using radial shading for each individual square. You might achieve a poor man's shading by shifting the grid and using opacity. May 29, 2017 at 11:05
• "more like the top view of a real life mattress?" The question is how a real life mattress would like look?! What is the final output you're looking for? May 29, 2017 at 13:11
• @Croco: I have no specific image in mind that I want to aim for, I simply hope to achieve a picture where people who look at it say "it's a mattress!", and not "that ice-cream cone has a weird shape", as could be possible with the grid. May 29, 2017 at 17:29

Sort of OK...

\documentclass[tikz,border=5]{standalone}
\begin{document}
\begin{tikzpicture}[looseness=0.5]
rounded corners=0.25cm] (-.125,-.125) rectangle (6.125,8.125);
\foreach \x in {0,...,5} \foreach \y in {0,...,7}
(0,0)
to [bend left] (0,1/2) to [bend right] (0,1)
to [bend left] (1,1)
to [bend left] (1,0.5) to [bend right] (1,0)
to [bend right] cycle;
\end{tikzpicture}
\end{document}


• My favourite, although I would prefer inverted colours of the seams and of the cases. This would give the seams a more sunken-in appearance. May 30, 2017 at 8:03
• Looks comfortable! May 31, 2017 at 7:10
• Ah, this is the type of things for which I just do not have enough experience. I like it a lot, this is the mattress I ended up using, albeit with the suggestions by AlexG. I have the first shading going from left black!10 to right black!15, and the small shadings from left white to right black!20. Finally, I used 10 by 8 smaller shadings. Now, so fluffy, must resist taking a nap... Jun 2, 2017 at 7:47

Just for fun, another solution:

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\begin{document}

With wavy lines:

\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

\path[rounded corners=2mm,use as bounding box,clip] (0,0) rectangle (\br,\ht);

\fill[gray!30](0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrcurve{6}
\pgfmathsetmacro\nrrow{12}

\pgfmathsetmacro\brcurve{\br/\nrcurve}
\pgfmathsetmacro\brcurvepart{\br/\nrcurve/4}
\pgfmathsetmacro\rowht{\ht/\nrrow}
\pgfmathsetmacro\curveampl{\rowht/5}

\newcommand\curvepart[2]{
(#1,#2+\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2-\curveampl)
(#1+\brcurvepart*2,#2-\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2+\curveampl)
}
\newcommand\curvepartneg[2]{
(#1,#2-\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2+\curveampl)
(#1+\brcurvepart*2,#2+\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2-\curveampl)
}

\draw[line width=1pt,black!75]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2}
}
};

\begin{scope}[yshift=1pt]
\draw[line width=1pt,gray!60]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2}
}
};
\end{scope}

\begin{scope}[yshift=-1pt]
\draw[line width=1pt,gray!15]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2}
}
};
\end{scope}

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}

With grid pattern:

\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

\path[rounded corners=2mm,use as bounding box,clip] (0,0) rectangle (\br,\ht);

\fill[gray!30](0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrlines{12}
\pgfmathsetmacro\linediff{\ht/12+\br/12}

\draw[line width=1pt,black!75]
\foreach \x in {2,...,\nrlines} {
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht)
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0)
};

\begin{scope}[yshift=1pt]
\draw[line width=1pt,gray!60]
\foreach \x in {2,...,\nrlines} {
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht)
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0)
};
\end{scope}

\begin{scope}[yshift=-1pt]
\draw[line width=1pt,gray!15]
\foreach \x in {2,...,\nrlines} {
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht)
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0)
};
\end{scope}

\fill[white]    (0,-1) rectangle (-\ht,\ht+1)
(\br,-1) rectangle (\br+\ht,\ht+1);

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}
\end{document}


The first looks good to me, but the second looks more like beveled glass.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

%\useasboundingbox (0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrcurve{6}
\pgfmathsetmacro\nrrow{12}

\pgfmathsetmacro\brcurve{\br/\nrcurve}
\pgfmathsetmacro\brcurvepart{\br/\nrcurve/4}
\pgfmathsetmacro\rowht{\ht/\nrrow}
\pgfmathsetmacro\curveampl{\rowht/5}

\newcommand\curvepart[2]{
(#1,#2+\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2-\curveampl)
(#1+\brcurvepart*2,#2-\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2+\curveampl)
}
\newcommand\curvepartneg[2]{
(#1,#2-\curveampl) cos (#1+\brcurvepart,#2)
(#1+\brcurvepart,#2) sin (#1+\brcurvepart*2,#2+\curveampl)
(#1+\brcurvepart*2,#2+\curveampl) cos (#1+\brcurvepart*3,#2)
(#1+\brcurvepart*3,#2) sin (#1+\brcurvepart*4,#2-\curveampl)
}

\draw[line width=5pt,color=lightgray]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2} } };

\draw[line width=1pt,color=gray]
\foreach \x in {1,2,...,\nrcurve} {
\foreach \y in {2,4,...,\nrrow} {
\curvepart{\brcurve*\x-\brcurve}{\rowht*\y - \rowht/2 - \rowht}
\curvepartneg{\brcurve*\x-\brcurve}{\rowht*\y-\rowht/2} } };

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}
%
\begin{tikzpicture}[x=0.3cm,y=0.3cm]
\pgfmathsetmacro\br{16}
\pgfmathsetmacro\ht{20}

%\useasboundingbox (0,0) rectangle (\br,\ht);

\pgfmathsetmacro\nrlines{12}
\pgfmathsetmacro\linediff{\ht/12+\br/12}

\begin{scope}
\clip[rounded corners=2mm] (0,0) rectangle (\br,\ht);

\draw[rounded corners=2mm,line width=4pt,color=lightgray] (0,0) rectangle (\br,\ht);

\foreach \x in {2,...,\nrlines} {
\draw[line width=5pt,color=lightgray]
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht);
\draw[line width=5pt,color=lightgray]
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0);
}

\draw[line width=1pt,color=gray]
\foreach \x in {2,...,\nrlines} {
(-\ht+\x*\linediff-\linediff,0) -- (\x*\linediff-\linediff,\ht)
(-\ht+\x*\linediff-\linediff,\ht) -- (\x*\linediff-\linediff,0)
};
\end{scope}

\coordinate (A) at (0,0);
\coordinate (B) at (0,\ht);
\coordinate (C) at (\br,\ht);
\coordinate (D) at (\br,0);

\draw[rounded corners=2mm,line width=1pt] (A) -- (B) -- (C) -- (D) -- cycle;
\end{tikzpicture}
\end{document}


I have kind of a weird love-hate relationship with Unicode...

\documentclass{article}
\usepackage{fontspec}
\setmainfont[Scale=20]{Symbola}
\begin{document}
\Uchar"1F6CF
\end{document}


• Not related with a mattress but I like to see knew ideas that are possible to be done with LaTeX... ;) +1 May 31, 2017 at 8:25
• @Henri Menke Where could be found the Symbola font file ? Mar 31, 2018 at 3:06
• @SDrolet That is actually a very good question, because the offical website does not have a download link (anymore?). But the license permits redistribution, so I uploaded the file for you here transfer.sh/6AQpo/Symbola_hint.ttf (link valid for 14 days). There is also a backup from 2018/03/07 on archive.org: web.archive.org/web/20180307013123/http://users.teilar.gr/… Mar 31, 2018 at 4:07