24

My usual what-can-I-plot-today resulted in this:

Surface plot of a girl

It's based on the math function by mikuszefski posted on mathematica.stackexchange.com.

I implemented it in TeX with pgfplots this way:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{
  width  = 7cm,
  compat = 1.14,
  /pgf/declare function = {
    bx(\a,\b,\c,\d,\e) = tanh(\d*(\a-\b)) + tanh(-1*\e*(\a-\c));
    ex(\x,\y,\z)       = exp(-1*(\x-\y)^2/\z);
    ra(\x,\y)          = 0.4*(1-0.4*ex(\x,0.8,0.15) + sin(2*pi*\y)^2
       + 0.6*ex(\x,0.8,0.25)*cos(2*pi*\y)^2
       + 0.3*cos(2*pi*\y))*0.5*(1+tanh(4*\x))
       + (1-0.2*ex(\x,-1.3,0.9))*0.5*(1+tanh(-4*\x))*(0.5*(1+sin(2*pi*\y)^2
       + 0.3*cos(2*pi*\y))*((abs(sin(2*pi*\y)))^1.3+0.08*(1+tanh(4*\x))))
       + 0.13*bx(cos(pi*\y),-0.45,0.45,5,5)*bx(\x,-0.5,0.2,4,2)
       - 0.1*bx(cos(pi*\y),-0.008,0.008,30,30)*bx(\x,-0.4,0.25,8,6)
       - 0.05*sin(pi*\y)^16*bx(\x,-0.55,-0.35,8,18);
  }
}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
      small,
      trig format plots = rad,% radian instead of deg
      grid              = major,% thin gray grid lines 
      z post scale      = 3,% scaling height
      samples           = 100,% use 20 for low res quicker compiling
      samples y         = 30,%  use 20 for low res quicker compiling
      z buffer          = sort,% sort according to depth of point
      zmax              = 2,
      colormap          = {skin}{rgb255=(255,105,180) rgb255=(255,240,245)},
      draw              = mapped color!95!black,% lighter mesh lines
      view              = {-45}{10},
      %view             = {45}{15},% different view
    ]
    \addplot3[
      surf,
      shader   = faceted interp,
      domain   = 0:1,
      domain y = -1.5:1.5,
    ] 
    ( { 0.1*exp(-1*(y-0.8)^2/0.6)-0.18*exp(-1*(y-0.1)^2/0.4) +
        ra(y,x)*cos(2*pi*x) },
      { ra(y,x)*sin(2*pi*x) },
      { y } );
  \end{axis}
\end{tikzpicture}
\end{document}

I wonder if the surface can be improved, such as with a better shading (shader=interp doesn't look great), no mesh or decent mesh, other patch type, different color map - how can you make this girl look great?

(PS: just today and tomorrow (Monday) my 2 books full of examples are available for $5 each, see: blog post. No naked girl on cover though.)

  • 9
    Oh, math porn. :-) – Johannes_B Jan 8 '17 at 15:03
  • @Johannes_B Now you added that keyword for google. :-) – Stefan Kottwitz Jan 8 '17 at 15:07
  • 11
    SE team will wonder why traffic goes up by 50 % within the next week. :-) – Johannes_B Jan 8 '17 at 15:08
  • 3
    Colour ‘Cuisse de nymphe émue’ seems to be unavoidable… – Bernard Jan 8 '17 at 15:10
  • I guess package pst-solides3d is something you are searching for. – Michael Fraiman Jun 6 '17 at 16:18
6

Using the interp shader with the color linear in x, you can get an interesting lighting. I also changed the color for an antique sculpture look:

rendering

\documentclass[border=10pt]{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{
  width  = 7cm,
  compat = 1.14,
  /pgf/declare function = {
    bx(\a,\b,\c,\d,\e) = tanh(\d*(\a-\b)) + tanh(-1*\e*(\a-\c));
    ex(\x,\y,\z)       = exp(-1*(\x-\y)^2/\z);
    ra(\x,\y)          = 0.4*(1-0.4*ex(\x,0.8,0.15) + sin(2*pi*\y)^2
       + 0.6*ex(\x,0.8,0.25)*cos(2*pi*\y)^2
       + 0.3*cos(2*pi*\y))*0.5*(1+tanh(4*\x))
       + (1-0.2*ex(\x,-1.3,0.9))*0.5*(1+tanh(-4*\x))*(0.5*(1+sin(2*pi*\y)^2
       + 0.3*cos(2*pi*\y))*((abs(sin(2*pi*\y)))^1.3+0.08*(1+tanh(4*\x))))
       + 0.13*bx(cos(pi*\y),-0.45,0.45,5,5)*bx(\x,-0.5,0.2,4,2)
       - 0.1*bx(cos(pi*\y),-0.008,0.008,30,30)*bx(\x,-0.4,0.25,8,6)
       - 0.05*sin(pi*\y)^16*bx(\x,-0.55,-0.35,8,18);
  }
}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
      small,
      trig format plots = rad,% radian instead of deg
      z post scale      = 3,% scaling height
      samples           = 100,% use 20 for low res quicker compiling
      samples y         = 30,%  use 20 for low res quicker compiling
      z buffer          = sort,% sort according to depth of point
      zmax              = 2,
      colormap          = {skin}{color=(AntiqueWhite) color=(AntiqueWhite!40!DimGrey)},
      view              = {-45}{10},
      %view             = {45}{15},% different view
    ]
    \addplot3[
      surf,
      shader   = interp,
      domain   = 0:1,
      domain y = -1.5:1.5,
      point meta={x},
    ] 
    ( { 0.1*exp(-1*(y-0.8)^2/0.6)-0.18*exp(-1*(y-0.1)^2/0.4) +
        ra(y,x)*cos(2*pi*x) },
      { ra(y,x)*sin(2*pi*x) },
      { y } );
  \end{axis}
\end{tikzpicture}
\end{document}

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.