15

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:

Two TikZ mattresses

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

4
  • 1
    At first I thought "mattress" was a typo for "matrix" :) (+1, btw)!
    – CarLaTeX
    May 29, 2017 at 8:04
  • 1
    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?
    – CroCo
    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

4 Answers 4

28

Sort of OK...

\documentclass[tikz,border=5]{standalone}
\begin{document}
\begin{tikzpicture}[looseness=0.5]
\shade [left color=gray!20, right color=gray!10, shading angle=45,
  rounded corners=0.25cm] (-.125,-.125) rectangle (6.125,8.125);
\foreach \x in {0,...,5} \foreach \y in {0,...,7}
  \shade [left color=gray!20, right color=white, shading angle=45, shift={(\x,\y)}] 
    (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}

enter image description here

3
  • 1
    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.
    – AlexG
    May 30, 2017 at 8:03
  • Looks comfortable!
    – jub0bs
    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
13

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}

enter image description here

8

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

demo

\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}
3

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

Here is Unicode Character 'BED' (U+1F6CF).

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

enter image description here

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.