Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Task

Show off your best scientific illustration !

The main purpose of this question is to share beautiful scientific pictures, preferably with an educational aspect.


Content

Your post must contain a nice picture and the associated code. One can post several pictures, but it must be done in different replies. Of course, it must be done with LaTeX & Friends : the post must start with a short sentence to present the language that you chose (TikZ, Asymptote ...) and the main packages that helped you to make the picture. Don't hesitate to add comments.


Reward

The satisfaction to share without expecting a reward :)

Ok ... 300 points reputation bounty for the best up-voted post until the 15th of Feb.


Related links

I'll contact Texample.net webmaster to see if he is interested to share the best illustrations, with the participant's agreement of course.

Contest: Show Off Your Skillz in TeX & Friends

share|improve this question
11  
that's easy :p dx.doi.org/10.1007/978-3-642-36763-2_46 –  percusse Feb 5 at 8:43
12  
I'll be glad if Till Tantau himself decide to participate, but that would be a bit unfair ... :) –  Thomas Feb 5 at 8:47
6  
I'm surprised this question wasn't closed already by people like this, on the grounds that it's not a question. Or does that apply only to SO, not to tex.SE? –  Dan Dascalescu Feb 7 at 0:06
6  
@DanDascalescu: Here on TeX.SX the mood is much more laazyyy. Think alone the existence of a tag big-list (click on it). –  Speravir Feb 7 at 0:22
4  
A fantastic proposition... Such "competitions" should be held more often... –  Aashutosh Feb 7 at 5:51

51 Answers 51

up vote 4 down vote accepted

Here are some of the pictures from my master thesis. The topic were transmission and reflexion of (sound) waves at the open end of a tube.

All images are made with TikZ and pgfplots. Many thanks to Christian Feuersänger for showing how to do the wave shadings!

All images are shown in one document, which I split in parts for this answer. To compile it on your machine you must put all fragments in one document; and gnuplotis required, too.

% !TeX encoding = utf8
\documentclass[
   11pt,cmyk,
   multi={tikzpicture},
   border=10mm,
]{standalone}


% General packages
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{helvet}
\usepackage[garamond]{mathdesign}
\usepackage{mathtools}

% Colors
\usepackage{xcolor}
   \definecolor{spot}{cmyk}{1,0.20,0,0}
   \colorlet{gray}{black!60}
   \colorlet{wave}{spot}

% Load TikZ and libraries
\usepackage{tikz}
\usetikzlibrary{calc,positioning,decorations.pathmorphing,%
   arrows.meta,backgrounds}
% Define TikZ styles etc.
\tikzset{
   every plot/.style={
      prefix=plots/,
      samples=200,
   },
   every node/.style={
      font=\footnotesize,
   },
   line width=1pt,
   shorten/.style={
      shorten >=#1,
      shorten <=#1,
   },
   >=Triangle[],
   axis/.style={-Stealth[]},
   tick/.style={
      axis,
      shorten <=-0.5\pgflinewidth,
      shorten >=-0.5\pgflinewidth,
   },
}

% Load and configure pgfplots
\usepackage{pgfplots}
   \usepgfplotslibrary{polar}
   \pgfplotsset{
      compat=1.11,
      wave axis/.style={
         view={0}{90},
         hide axis,
         colormap={custom}{color=(white) color=(wave)},
         trig format plots=rad,
         trig format=rad,
         x=1cm,
         y=1cm,
         z=0cm,
         anchor=origin,
      },
      wave plot/.style={
         samples=200,
         samples y=2,
         surf,shader=interp,
      },
      polar wave plot/.style={
         data cs=polar,
         domain=0:2*pi,
         samples y=100,
         surf,shader=interp,
      },
   }

% Macro for subfigure captions
\newcommand{\subfig}[1]{\textbf{\textsf{#1)}}~}

\begin{document}

Modes of a wave in a tube

modes

\begin{tikzpicture}[
   tube/.style={ultra thick,black},
   wave/.style={thick,gray},
]
   % define variables
   %% tube size
   \def\H{.9}
   \def\L{5.5}
   %% distances
   \def\A{0.3}
   \def\B{0.5}
   %% wave's amplitude
   \pgfmathsetmacro\a{0.35}
   % both ends open or closed
   \foreach \n in {1,2,3,4,5} {
      \begin{scope}[shift={(0,-\n*\H-\n*\A)}]
         % closed ends
         %% wave
         \begin{scope}
            % air pressure
            \begin{axis}[wave axis]
               \addplot3[wave plot,domain=0:\L,domain y=-\H/2:\H/2] {abs(sin(pi/\L * \n * x))};
%               \addplot[domain=0:\L,samples=100] function {abs(sin(pi/\L * \n * x))};
            \end{axis}
            % wave form
            \draw [wave]
               plot [id=moden-gg-1-\n, domain=0:\L] function {\a * sin(pi/\L * \n * x)}
               plot [id=moden-gg-2-\n, domain=0:\L] function {-\a * sin(pi/\L * \n * x)};
         \end{scope}
         %% tube
         \draw [tube] (\L,-\H/2) -| (0,\H/2) -- (\L,\H/2) -- cycle;
         %% coordinates for later use
         \coordinate (GG-\n) at (0,0);
         \coordinate (B1) at (0,-\H/2);
         % open ends
         \begin{scope}[shift={(\L+\B,0)}]
            %% wave
            \begin{scope}
               % air pressure
               \begin{axis}[wave axis]
                  \addplot3[wave plot,domain=0:\L,domain y=-\H/2:\H/2] {abs(cos(pi/\L * \n * x))};
%                  \addplot[domain=0:\L,samples=100] function {abs(cos(pi/\L * \n * x))};
               \end{axis}
               % wave
               \draw [wave]
                  plot [id=moden-oo-1-\n, domain=0:\L] function {\a * cos(pi/\L * \n * x)}
                  plot [id=moden-oo-2-\n, domain=0:\L] function {-\a * cos(pi/\L * \n * x)};
            \end{scope}
            %% tube
            \draw [tube] (0,-\H/2) -- (\L,-\H/2) (0,\H/2) -- (\L,\H/2);
            %% coordinates
            \coordinate (B2) at (0,-\H/2);
         \end{scope}
      \end{scope}
   }
   \foreach \n in {1,3,5} {
      \begin{scope}[shift={(0,-\n*\H-\n*\A)}]
         % one end open, one closed
         \begin{scope}[shift={(2*\L+2*\B,0)}]
            %% wave
            \begin{scope}
               % air pressure
               \begin{axis}[wave axis]
                  \addplot3[wave plot,domain=0:\L,domain y=-\H/2:\H/2] {abs(sin(pi/\L * (\n-0.5) * x))};
%                  \addplot[domain=0:\L,samples=100] function {abs(sin(pi/\L * (\n-0.5) * x))};
               \end{axis}
               % wave
               \draw [wave]
                  plot [id=moden-go-1-\n, domain=0:\L] function {\a * sin(pi/\L * (\n-0.5) * x)}
                  plot [id=moden-go-2-\n, domain=0:\L] function {-\a * sin(pi/\L * (\n-0.5) * x)};
            \end{scope}
            %% tube
            \draw [tube] (\L,-\H/2) -| (0,\H/2) -- (\L,\H/2);
            %% coordinates
            \coordinate (B3) at (0,-\H/2);
         \end{scope}
      \end{scope}
   }
   % captions/text
   \foreach \n in {1,2,3,4,5} {
      \node at (GG-\n) [rotate=90,left=4pt,anchor=south,inner sep=0pt] {$n=\n$};
   }
   \node  at (B1) [below right=1.5mm and 0mm,inner sep=0pt] {\subfig{a}{closed/closed}};
   \node  at (B2) [below right=1.5mm and 0mm,inner sep=0pt] {\subfig{b}{open/open}};
   \node  at (B3) [below right=1.5mm and 0mm,inner sep=0pt] {\subfig{c}{closed/open}};
\end{tikzpicture}

Wave moves through five points (particles)

moving wave

\begin{tikzpicture}
   % define variables
   %% wave
   \pgfmathsetmacro\T{9}
   \pgfmathsetmacro\A{1.75}
   %% oscillations
   \pgfmathsetmacro\Ti{1.5}
   \pgfmathsetmacro\Ai{0.6}
   \pgfmathsetmacro\yMax{1}
   \pgfmathsetmacro\xMax{2*\Ti+0.3}
   \pgfmathsetmacro\D{2*\Ti+0.2}
   \coordinate (S) at (0,-2.7);
   % wave
   %% axis
   \draw [axis] (0,-2) -- (0,2.6) node [left] {$z(x,0)$};
   \draw [axis] (0,0) -- (10,0) node [below] {$x$};
   \draw [tick, |-] (0,\A) node [left] {$z_\text{m}$} -- (0,0);
   %% wave langth
   \draw [|-|] (0,2.2) -- ++ (\T,0) node [midway,above] {$\lambda$};
   %% wave form
   \draw [ultra thick, gray] plot [id=welle, domain=-\yMax-0.1:\T+\yMax]
      function {\A*sin(2*pi/\T*x)};
   \pgfmathsetmacro\X{0.425*\T}
   \pgfmathsetmacro\Y{\A*sin(2*pi/\T*\X r)}
   \draw [gray] (\X,\Y) -- ++(35:0.7) node [right,align=left]
      {\textbf{snapshot} of wave\\ at time $t=0$};;
   %% oscillating points
   \coordinate (1) at (0.00*\T,0);
   \coordinate (2) at (0.25*\T,\A);
   \coordinate (3) at (0.50*\T,0);
   \coordinate (4) at (0.75*\T,-\A);
   \coordinate (5) at (1.00*\T,0);
   \coordinate (6) at (1.25*\T,\A);
   \foreach \n in {1,2,3,4,5} {
      \node (n\n) at (\n) [
         circle,
         font=\sffamily\scriptsize,
         spot,
         draw, ultra thick,
         fill=white,
         inner sep=0pt,
         minimum size=3mm,
         outer sep=1mm,
      ] {\n};
   }
   %% movment of points
   \draw [spot,thick,->] (n1) -- ++(0,-0.5*\A);
   \draw [spot,thick,->] (n2) -- ++(0,-0.5*\A);
   \draw [spot,thick,->] (n3) -- ++(0,0.5*\A);
   \draw [spot,thick,->] (n4) -- ++(0,0.5*\A);
   \draw [spot,thick,->] (n5) -- ++(0,-0.5*\A);
   % oscillations
   \begin{scope}[shift={($(1)+(S)$)}, rotate=-90]
      %% axis
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_1(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      %% sine form
      \draw [thick, spot] plot [id=welle-schwingung-1, domain=0:\D]
         function {-\Ai*sin(2*pi/\Ti*x))};
      %% ponts
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {1};
      %% movment
      \draw [spot,thick,-{Triangle[scale=0.7]}] (n) -- ++(0,-\Ai);
      %% origin coordinate for later use
      \coordinate (U1) at (0,0);
      %% root coordinate for later use
      \coordinate (N1) at (3*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(2)+(S)+(0,-\A)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_2(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=welle-schwingung-2, domain=0:\D]
         function {\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {2};
      \draw [spot,thick,-{Triangle[scale=0.7]}] (n) -- ++(0,-\Ai);
      \coordinate (N2) at (4*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(3)+(S)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_3(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=welle-schwingung-3, domain=0:\D]
         function {-\Ai*sin(2*pi/\Ti*x+pi)};
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {3};
      \draw [spot,thick,-{Triangle[scale=0.7]}] (n) -- ++(0,\Ai);
      \coordinate (N3) at (5*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(4)+(S)+(0,\A)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_4(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=welle-schwingung-4, domain=0:\D]
         function {\Ai*sin(2*pi/\Ti*x+3*pi/2)};
      \node (n) at (0,-\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {4};
      \draw [spot,thick,-{Triangle[scale=0.7]}] (n) -- ++(0,\Ai);
      \coordinate (N4) at (6*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(5)+(S)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_5(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=welle-schwingung-5, domain=0:\D]
         function {-\Ai*sin(2*pi/\Ti*x+2*pi)};
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {5};
      \draw [spot,thick,-{Triangle[scale=0.7]}] (n) -- ++(0,-\Ai);
      \coordinate (U5) at (0,0);
      \coordinate (N5) at (7*\Ti/4,0);
   \end{scope}
   % help lines
   \foreach \x in {0.25,0.5,...,2} {
      \begin{scope}[on background layer]
         \draw [dotted] ($(U1)+(-\yMax,-\x*\Ti)$) -- ($(U5)+(\yMax,-\x*\Ti)$);
      \end{scope}
   }
   % pahse shift
   \foreach \n [remember=\n as \lastn (initially 1)] in {2,3,4,5} {
      \draw [gray,thick] (N\lastn) -| ($(N\lastn)!0.5!(N\n)$) |- (N\n);
   }
   \draw [gray,thick] (N1) -- ++(-\yMax,0);
   \draw [gray,thick] (N5) -- ++(\yMax,0);
\end{tikzpicture}

Standing wave

standing wave

\begin{tikzpicture}
   % define variables
   %% wave
   \pgfmathsetmacro\T{9}
   \pgfmathsetmacro\A{1.75}
   %% oscillations
   \pgfmathsetmacro\Ti{0.9}
   \pgfmathsetmacro\Ai{0.3}
   \pgfmathsetmacro\yMax{0.5}
   \pgfmathsetmacro\xMax{2*\Ti+0.3}
   \pgfmathsetmacro\D{2*\Ti+0.1}
   \coordinate (S) at (0,-2.7);
   % wave
   %% axis
   \draw [axis] (0,-2) -- (0,2.6) node [left] {$z(x,t_0)$};
   \draw [axis] (0,0) -- (10,0) node [below] {$x$};
   \draw [tick, |-] (0,\A) node [left] {$z_\text{m}$} -- (0,0);
   %% wave length
   \draw [|-|] (0,2.2) -- ++ (\T,0) node [midway,above] {$\lambda$};
   %% wave form
   \draw [ultra thick, gray] plot [id=stehende-welle, domain=-\yMax-0.1:\T+\yMax]
      function {\A*sin(2*pi/\T*x)};
   \pgfmathsetmacro\X{0.425*\T}
   \pgfmathsetmacro\Y{\A*sin(2*pi/\T*\X r)}
   \draw [gray] (\X,\Y) -- ++(35:0.7) node [right,align=left]
      {\textbf{snapshot} of wave\\ at time $t=t_0$};
   %% osizllationg points (II)
   \coordinate (1) at (0.00*\T,0);
   \coordinate (2) at (0.25*\T,\A);
   \coordinate (3) at (0.50*\T,0);
   \coordinate (4) at (0.75*\T,-\A);
   \coordinate (5) at (1.00*\T,0);
   \pgfmathsetmacro\X{0.125*\T}
   \pgfmathsetmacro\Yvi{\A*sin(2*pi/\T*\X r)}
   \coordinate (6) at (\X,\Yvi);
   \pgfmathsetmacro\X{0.375*\T}
   \pgfmathsetmacro\Yvii{\A*sin(2*pi/\T*\X r)}
   \coordinate (7) at (\X,\Yvii);
   \pgfmathsetmacro\X{0.625*\T}
   \pgfmathsetmacro\Yviii{\A*sin(2*pi/\T*\X r)}
   \coordinate (8) at (\X,\Yviii);
   \pgfmathsetmacro\X{0.875*\T}
   \pgfmathsetmacro\Yix{\A*sin(2*pi/\T*\X r)}
   \coordinate (9) at (\X,\Yix);
   \foreach \n in {1,2,3,4,5,6,7,8,9} {
      \node (n\n) at (\n) [
         circle,
         font=\sffamily\scriptsize,
         spot,
         draw, ultra thick,
         fill=white,
         inner sep=0pt,
         minimum size=3mm,
         outer sep=1mm,
      ] {\n};
   }
   %% movment of points
   \draw [spot,thick,->] (n2) -- ++(0,-0.5*\A);
   \draw [spot,thick,->] (n4) -- ++(0,0.5*\A);
   \draw [spot,thick,->] (n6) -- ++(0,-0.5*\Yvi);
   \draw [spot,thick,->] (n7) -- ++(0,-0.5*\Yvii);
   \draw [spot,thick,->] (n8) -- ++(0,-0.5*\Yviii);
   \draw [spot,thick,->] (n9) -- ++(0,-0.5*\Yix);
   % oscillations
   \begin{scope}[shift={($(1)+(S)$)}, rotate=-90]
      %% axis
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_1(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      %% sine form
      \draw [thick, spot] plot [id=stehende-welle-schwingung-1, domain=0:\D]
         function {0};
      %% oscillating point (particle)
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {1};
      %% origin coordinate for later use
      \coordinate (U1) at (0,0);
      %% root coordinate for later use
      \coordinate (N1) at (5*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(2)+(S)+(0,-\A)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_2(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-2, domain=0:\D]
         function {\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {2};
   \end{scope}
   \begin{scope}[shift={($(3)+(S)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_3(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-3, domain=0:\D]
         function {0};
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {3};
   \end{scope}
   \begin{scope}[shift={($(4)+(S)+(0,\A)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_4(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-4, domain=0:\D]
         function {-\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,-\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {4};
   \end{scope}
   \begin{scope}[shift={($(5)+(S)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_5(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-5, domain=0:\D]
         function {0};
      \node (n) at (0,0) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {5};
      \coordinate (U5) at (0,0);
      \coordinate (N5) at (5*\Ti/4,0);
   \end{scope}
   \begin{scope}[shift={($(6)+(S)-(0,\Yvi)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_6(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-6, domain=0:\D]
         function {\Yvi/\A*\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Yvi/\A*\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {6};
      \coordinate (U6) at (0,0);
   \end{scope}
   \begin{scope}[shift={($(7)+(S)-(0,\Yvii)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_7(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-7, domain=0:\D]
         function {\Yvii/\A*\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Yvii/\A*\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {7};
      \coordinate (U7) at (0,0);
   \end{scope}
   \begin{scope}[shift={($(8)+(S)-(0,\Yviii)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_8(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-8, domain=0:\D]
         function {\Yviii/\A*\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Yviii/\A*\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {8};
      \coordinate (U8) at (0,0);
   \end{scope}
   \begin{scope}[shift={($(9)+(S)-(0,\Yix)$)}, rotate=-90]
      \draw [axis] (0,-\yMax) -- (0,\yMax) node [above,midway] {$z_9(t)$};
      \draw [axis] (0,0) -- (\xMax,0) node [right] {$t$};
      \draw [thick, spot] plot [id=stehende-welle-schwingung-9, domain=0:\D]
         function {\Yix/\A*\Ai*sin(2*pi/\Ti*x+pi/2)};
      \node (n) at (0,\Yix/\A*\Ai) [
         circle,
         font=\sffamily\tiny,
         spot,
         draw, thick,
         fill=white,
         inner sep=0pt,
         minimum size=2mm,
         outer sep=0.5mm,
      ] {9};
      \coordinate (U9) at (0,0);
   \end{scope}
   % help lines
   \foreach \x in {0.25,0.5,...,2} {
      \begin{scope}[on background layer]
         \draw [dotted] ($(U1)+(-\yMax,-\x*\Ti)$) -- ($(U5)+(\yMax,-\x*\Ti)$);
      \end{scope}
   }
   % (no) phase shift
   \draw [gray,thick] ($(N1)-(\yMax,0)$) -- ($(N5)+(\yMax,0)$);
\end{tikzpicture}

Organ pipe

organ pipe

\begin{tikzpicture}
   % define varaibles
   %% pipe foot
   \def\F{2.25}
   \def\r{0.1}
   %% wave length
   \def\w{20}
   %% amplitude
   \def\z{0.5}
   %% wave body
   \def\R{0.6}
   \pgfmathsetmacro\l{0.6*\R}
   \pgfmathsetmacro\L{\w/2-\l}
   %% cut
   \def\A{0.8}
   \def\hA{0.4}
   %% distance for captions
   \pgfmathsetmacro\B{\R+0.3}
   % wave
   \draw [ultra thick, spot,fill=spot!20] plot [id=pfeifen-welle-1,domain=0:\w/2] function
      {\z*sin(2*pi/\w*x)};
   \draw [ultra thick, spot,fill=spot!20] plot [id=pfeifen-welle-2,domain=0:\w/2] function
      {-\z*sin(2*pi/\w*x)};
   % axis
   \draw [axis] (-\F-\hA-\A/2,0) -- (\w/2+0.35,0) node [below left] {$x$};
   % pipe
   \draw [ultra thick] (-\F-\hA-\A/2,-\r) -- (-\hA-\A/2,-\R) -- (\L,-\R)
      (-\F-\hA-\A/2,\r) -- (-\hA-\A/2,\R) -- ++(\hA,0) ++(\A,0) -- (\L,\R);
   ;
   \draw [line width=3pt] (0,-\R) -- (0,\R-\A/8);
   \draw [dashed] (\L,-\R) -- (\L,\R);
   % captions
   \node at (\w/4,0) [spot,fill=spot!20] {$\Delta p(x,0)$};
   \draw [tick, |-|] (-\F-\hA-\A/2,-\B) -- (0,-\B) node [midway,below] {foot length};
   \draw [tick, |-|] (0,-\B) -- (\L,-\B) node [midway,below] {reduced length $L_\text{r}$};
   \draw [tick, |-|] (\L,-\B) -- (\L+\l,-\B) node [midway,below] {$\ell$};
   \draw [tick, |-|] (0,\B) -- (\w/2,\B) node [midway,above] {theoretical length $L$};
\end{tikzpicture}

Helmholtz’ model for the open end

helmholtz model

\begin{tikzpicture}
   % define variables
   \def\H{0.275}
   \def\S{1.8}
   \def\B{8}
   \def\T{4.5}
   \def\l{2.6}
   \def\s{0.3}
   \pgfmathsetmacro\w{atan((\S+\H/2)/\T)}
   \pgfmathsetmacro\R{sqrt(\T^2+(\S+\H/2)^2)}
   %% wave parameters
   \pgfmathsetmacro\wL{6.5*\H}
   \pgfmathsetmacro\wA{\H/2}
   \pgfmathsetmacro\D{10*\wL}
   % plane wave
   \begin{axis}[wave axis]
      \addplot3[wave plot,domain=-\B:0.05,domain y=-\wA:\wA] {abs(sin(pi/\wL * x))};
%      \addplot[domain=-\D:0,samples=200] function {abs(cos(pi/\wL * x))};
   \end{axis}
   % radial wave
   \begin{scope}
%      \clip (0,-\H/2-\S) -- (-\w:\R) arc [start angle=-\w, end angle=\w, radius=\R]
%         -- (0,\H/2+\S) -- cycle;
      \clip (0,-\H/2-\S) rectangle (\T,\H/2+\S);
      \begin{axis}[wave axis]
         \addplot3[polar wave plot,domain y=0:2*\T] function {abs(sin(pi/\wL * y))*exp(-0.2*y)};
%         \addplot[domain=0:2*\T,samples=200] function {abs(cos(pi/\wL * x))*exp(-0.2*x)};
      \end{axis}
   \end{scope}
   % tube
   \draw [ultra thick] (-\B,\H/2) -| (0,\H/2+\S);
   \draw [ultra thick] (-\B,-\H/2) -| (0,-\H/2-\S);
   % axis
   \draw [axis] (-\B,0) -- ($(\T,0)-(0.25,0)$) node [below left] {$x$};
   \draw [tick,|-] (0,0) node [below right=2pt and 2.5pt,inner sep=0pt] {$0$} -- (1,0);
   \draw [axis] (0,0) -- (25:2.5) node [below] {$\vec{r}$};
   % captions
   \draw (-2.5*\wL,0.25*\H) -- ++(65:.6) node [above] {$\psi_\text{i}$};
   \draw (60:\wL/1.9) -- ++(180:1.1) node [left] {$\psi_\text{a}$};
   \node at (0,-\H/2) [below left, align=right] {cross sectional\\area $A$};
\end{tikzpicture}
\end{document}
share|improve this answer

Radioactive dacay

Note: There is a screenshot of only the first half life of a nucleus but there are five half lifes for each version (but it can very easily be changed).

First version

\documentclass[
  dvipsnames
]{article}

\usepackage{lmodern}
\usepackage[
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}
\usepackage{fancyhdr}
\usepackage{pst-plot}
\usepackage[
  locale = DE
]{siunitx}
\usepackage{xfrac}
\usepackage{totcount}

%%% Constants %%%

\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

\def\HalveringerA{\calc{\Halveringer-1}}
\def\HalveringerB{\calc{\Halveringer+1}}
\def\konstA{\calc{10*2^(-\iA)}}
\def\konstI{\num{\calc{10*\konstA}}}
\def\konstB{\calc{2^(-\Halveringer)}}
\def\konstC{\calc{16*2^(-\iA)}}
\def\konstD{\calc{16-\konstC}}
\def\konstE{\calc{2*\Halveringer+0.25}}
\def\konstF{\calc{\konstE+0.25}}
\def\konstG{\calc{\konstE-0.25}}
\def\konstH{\calc{\konstE+0.55}}

%%% Definitions %%%

\def\radioaktivt{%
  \pscircle[
    fillstyle = solid,
    fillcolor = yellow,
    linestyle = none
  ](0,0){0.125}
  \pswedge*(0,0){0.125}{0}{60}
  \pswedge*(0,0){0.125}{120}{180}
  \pswedge*(0,0){0.125}{240}{300}
  \pscircle*[
    linecolor = yellow
  ](0,0){0.0375}
  \pscircle*(0,0){0.025}
}
\def\ikkeradioaktivt{%
  \pscircle*[
    linecolor = SeaGreen
  ](0,0){0.125}
}

\newcommand*\halveringer[1]{%
 \def\Halveringer{#1}
  \begin{pspicture}(-1.75,-0.7)(\konstH,11.05)
    \multido{\iA = 0+1, \rC = 0.25+2}{\Halveringer}{%
      \multido{\rA = \rC+0.5}{4}{%
        \multido{\rB = 0.27+0.635}{\konstC}{%
          \rput(\rA,\rB){\radioaktivt}%
        }%
      }%
    }
    \multido{\iA = 0+1, \rC = 0.25+2}{\Halveringer}{%
      \multido{\rA = \rC+0.5}{4}{%
        \multido{\rB = 9.795+-0.635}{\konstD}{%
          \rput(\rA,\rB){\ikkeradioaktivt}%
        }%
      }%
    }
    \multido{\iA = 0+1}{\Halveringer}{%
      \psline(!2   \iA\space mul     \konstA)%
             (!2 1 \iA\space add mul \konstA)%
             (!2 2 \iA\space mul add \konstA\space 2 div)%
    }
    \psline(!2 \Halveringer\space mul 10 \konstB\space mul)%
           (!2 \Halveringer\space mul 0)
    \psaxes[
      ticks = none,
      labels = none,
      arrowinset = 0.05,
      arrowscale = 1.6,
      arrowlength = 1.8
    ]{->}(0,0)(-0.3,-0.3)(\konstF,10.5)[$t$,0][Radioactive nuclei~(\si{\percent}),90]
    \psplot[
      algebraic,
      linecolor = red,
      linewidth = 1.5pt
    ]{0}{\konstG}{10*0.5^(0.5*x)}
    \psxTick(2){T_{\sfrac{1}{2}}}
    \multido{\iA = 4+2, \iB = 2+1}{\HalveringerA}{%
      \psxTick(\iA){\iB \cdot T_{\sfrac{1}{2}}}%
    }
    \multido{\iA = 0+1}{\HalveringerB}{%
      \psyTick(\konstA){\konstI}%
    }%
  \end{pspicture}%
}

\pagestyle{fancy}
\renewcommand*\headrulewidth{0pt}
\setlength\headheight{14.5pt}
\lhead{}
\rhead{}
\regtotcounter{page}
\cfoot{
  \ifnum \totvalue{page} > 1 \relax
    \thepage
  \else
%
  \fi
}

\begin{document}

%\begin{figure}[htbp]
% \centering
%  \begin{pspicture}(-2.4,-1.4)(2.4,2.9)
%    \pspolygon[
%      fillstyle = solid,
%      fillcolor = yellow,
%      linewidth = 5\pslinewidth
%    ](2.875;-30)(2.875;90)(2.875;210)
%    \pswedge*(0,0){1.25}{0}{60}
%    \pswedge*(0,0){1.25}{120}{180}
%    \pswedge*(0,0){1.25}{240}{300}
%    \pscircle*[
%      linecolor = yellow
%    ](0,0){0.375}
%    \pscircle*(0,0){0.25}
%  \end{pspicture}
%\end{figure}
%
%\begin{figure}[htbp]
% \centering
%  \begin{pspicture}(-1.8,-1.9)(1.8,1.9)
%    \psframe[
%      fillstyle = solid,
%      fillcolor = yellow,
%      linecolor = gray
%    ](-2,-2)(2,2)
%    \pswedge*(0,0){1.75}{0}{60}
%    \pswedge*(0,0){1.75}{120}{180}
%    \pswedge*(0,0){1.75}{240}{300}
%    \pscircle*[
%      linecolor = yellow
%    ](0,0){0.5}
%    \pscircle*(0,0){0.35}
%  \end{pspicture}
%\end{figure}
%\newpage

\multido{\iK = 1+1}{5}{%
  \begin{center}
    \halveringer{\iK}
  \end{center}
}

\end{document}

output1

Second version

\documentclass[
  dvipsnames
]{article}

\usepackage{lmodern}
\usepackage[
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}
\usepackage{fancyhdr}
\usepackage{
  pst-grad,
  pst-plot
}
\usepackage[
  locale = DE
]{siunitx}
\usepackage{xfrac}
\usepackage{totcount}

%%% Constants %%%

\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

\def\maerkerX{\calc{1.5*\i+0.75}}
\def\maerkerYa{\calc{10*2^(-\i)}}
\def\maerkerYb{\num{\calc{100*2^(-\i)}}}

\def\halveringerB{\calc{\Halveringer-1}}
\def\halveringerC{\calc{\Halveringer+1}}
\def\konstA{\calc{1.5*\i+0.25}\space}
\def\konstB{\calc{32*2^(-\i)}}
\def\konstC{\calc{32-\konstB}}
\def\konstD{\calc{1.5*\halveringerC+0.75}}
\def\konstE{\calc{\konstD-0.75}}
\def\konstF{\calc{\konstD+0.3}}

%%% Definitions %%%

\def\radioaktivt{%
  \psscalebox{0.0125}{%
    \pscircle[
      fillstyle = solid,
      fillcolor = yellow,
      linestyle = none
    ](0,0){5}
    \pswedge*(0,0){5}{0}{60}
    \pswedge*(0,0){5}{120}{180}
    \pswedge*(0,0){5}{240}{300}
    \pscircle*[
      linecolor = yellow
    ](0,0){1.5}
    \pscircle*(0,0){1}
  }
}

\def\ikkeradioaktivt{%
  \pscircle*[
    linecolor = SeaGreen
  ](0,0){0.0625}
}

\def\henfald{rand 301 mod 50 div round 50 div }
\def\simpel#1{!#1 \henfald add \henfald \i\space 5 mul 16 div add 0.121 add }

\newcommand*\halveringer[1]{%
 \def\Halveringer{#1}
  \begin{pspicture}(-1.75,-0.65)(\konstF,11.3)
    \psframe[
      linestyle = none,
      fillstyle = gradient,
      gradangle = 45,
      gradmidpoint = 1,
      gradbegin = gray!80,
      gradend = gray!30
    ](0,0)(\konstE,10.25)
    \multido{\i = 0+1}{\halveringerC}{%
      \psframe[
        dimen = middel,
        linecolor = NavyBlue,
        linewidth = 1pt,
        fillstyle = gradient,
        gradangle = 90,
        gradmidpoint = 1,
        gradbegin = NavyBlue!50,
        gradend = white
      ](\konstA,0)(!\konstA 1 add \maerkerYa)%
    }
    \multido{\i=0+1}{\halveringerC}{%
      \psframe[
        dimen = middel,
        linecolor = NavyBlue,
        linewidth = 1pt,
        fillstyle = gradient,
        gradangle = 90,
        gradmidpoint = 0,
        gradbegin = SeaGreen!30,
        gradend = white
      ](\konstA,10)(!\konstA 1 add \maerkerYa)%
    }
    \multido{\i = 0+1}{\halveringerC}{%
      \rput(\konstA,0){%
        \multido{\i = 0+1}{\konstB}{%
          \rput{!\henfald 777 mul}(\simpel{0.125}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.375}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.625}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.875}){\radioaktivt}%
        }%
      }
      \rput(\konstA,\maerkerYa){%
        \multido{\i = 0+1}{\konstC}{%
          \rput(\simpel{0.125}){\ikkeradioaktivt}
          \rput(\simpel{0.375}){\ikkeradioaktivt}
          \rput(\simpel{0.625}){\ikkeradioaktivt}
          \rput(\simpel{0.875}){\ikkeradioaktivt}%
        }%
      }%
    }
    \psaxes[
       ticks = none,
       labels = none,
       arrowinset = 0.05,
       arrowscale = 1.6,
       arrowlength = 1.8
    ]{->}(0,0)(-0.3,-0.3)(\konstD,10.75)[$t$,0][Radioactive nuclei~(\si{\percent}),90]
    \psplot[
      algebraic,
      linecolor = red,
      linewidth = 1.5pt
    ]{0.75}{\konstE}{10*0.5^(2*(x-0.75)/3)}
    \psxTick(0.75){\text{start}}
    \ifnum\Halveringer>0\relax
      \psxTick(2.25){T_{\sfrac{1}{2}}}
      \multido{\i = 2+1}{\halveringerB}{%
        \psxTick(\maerkerX){\i \cdot T_{\sfrac{1}{2}}}%
      }
      \multido{\i = 0+1}{\halveringerC}{%
        \psyTick(\maerkerYa){\maerkerYb}%
      }%
    \fi%
  \end{pspicture}%
}

\pagestyle{fancy}
\renewcommand*\headrulewidth{0pt}
\setlength\headheight{14.5pt}
\lhead{}
\rhead{}
\regtotcounter{page}
\cfoot{
  \ifnum \totvalue{page} > 1 \relax
    \thepage
  \else
%
  \fi
}

\begin{document}

\multido{\iK = 0+1}{6}{%
  \begin{center}
    \halveringer{\iK}
  \end{center}
}

\end{document}

output2

P.S. The macro names are is Danish but I hope it is understandable nonetheless.

share|improve this answer

Months after, this could be done with nice nested cycles and/or scopes, making the code 2 to 4 times shorter (and paying a bit more attention to colors)...but I still like the output of a tex I wrote very quickly, so I ended up to post it. This was then included in a calculus book for a degree course in Architecture, with great satisfaction for me also.

Riemann sums of a monotonic real function, in pure TikZ (arrows library for axes only):

Riemann sums of a monotonic function TikZ

\documentclass[multi=false,tikz=true,border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}

\begin{tikzpicture}
    \foreach \x in {0,.5,...,3.5} {%
        \draw[fill=cyan] (\x,0) -- (\x,{.25*(\x+.5)*(\x+.5)}) -- (\x+.5,{.25*(\x+.5)*(\x+.5)}) -- (\x+.5,0);
    }%
    \draw [thick,blue,domain=0:4] plot (\x,{.25*pow(\x,2)});
    \foreach \x in {0,.5,...,3.5} {%
        \draw[fill=orange] (\x,0) -- (\x,.25*\x*\x) -- (\x+.5,.25*\x*\x) -- (\x+.5,0);
    }%
    \draw [->,>=triangle 45] (-.5,0) -- (4.5,0) node[below] {\Large $x$};
    \draw [->,>=triangle 45] (0,-.5) -- (0,4.5) node[left] {\Large $y$};
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
    \foreach \x in {0,1,...,3} {%
        \draw[xshift=-6cm,fill=cyan] (\x,0) -- (\x,{.25*(\x+1)*(\x+1)}) -- (\x+1,{.25*(\x+1)*(\x+1)}) -- (\x+1,0);
    }%
    \draw [xshift=-6cm,thick,blue,domain=0:4] plot (\x,{.25*pow(\x,2)});
    \foreach \x in {0,1,...,3} {%
        \draw[xshift=-6cm,fill=orange] (\x,0) -- (\x,.25*\x*\x) -- (\x+1,.25*\x*\x) -- (\x+1,0);
    }%
    \draw [xshift=-6cm,->,>=triangle 45] (-.5,0) -- (4.5,0) node[below] {\Large $x$};
    \draw [xshift=-6cm,->,>=triangle 45] (0,-.5) -- (0,4.5) node[left] {\Large $y$};
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
    \foreach \x in {0,2} {%
        \draw[xshift=-12cm,fill=cyan] (\x,0) -- (\x,{.25*(\x+2)*(\x+2)}) -- (\x+2,{.25*(\x+2)*(\x+2)}) -- (\x+2,0);
    }%
    \draw [xshift=-12cm,thick,blue,domain=0:4] plot (\x,{.25*pow(\x,2)});
    \foreach \x in {0,2} {%
        \draw[xshift=-12cm,fill=orange] (\x,0) -- (\x,.25*\x*\x) -- (\x+2,.25*\x*\x) -- (\x+2,0);
    }%
    \draw [xshift=-12cm,->,>=triangle 45] (-.5,0) -- (4.5,0) node[below] {\Large $x$};
    \draw [xshift=-12cm,->,>=triangle 45] (0,-.5) -- (0,4.5) node[left] {\Large $y$};
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
    \foreach \x in {0,.25,...,3.75} {%
        \draw[xshift=6cm,fill=cyan] (\x,0) -- (\x,{.25*(\x+.25)*(\x+.25)}) -- (\x+.25,{.25*(\x+.25)*(\x+.25)}) -- (\x+.25,0);
    }%
    \draw [xshift=6cm,thick,blue,domain=0:4] plot (\x,{.25*pow(\x,2)});
    \foreach \x in {0,.25,...,3.75} {%
        \draw[xshift=6cm,fill=orange] (\x,0) -- (\x,.25*\x*\x) -- (\x+.25,.25*\x*\x) -- (\x+.25,0);
    }%
    \draw [xshift=6cm,->,>=triangle 45] (-.5,0) -- (4.5,0) node[below] {\Large $x$};
    \draw [xshift=6cm,->,>=triangle 45] (0,-.5) -- (0,4.5) node[left] {\Large $y$};
\end{tikzpicture}

\end{document}
share|improve this answer

A parameter varying hyperboloid.

enter image description here

\documentclass[pstricks,border=0pt]{standalone}
\usepackage{pst-solides3d}
%%%%%%%%%%%%%%%%%%
\begin{document}
\psset{unit=.15\columnwidth,viewpoint=10 45 25 rtp2xyz,linewidth=.4pt,Decran=10,lightsrc=3 2 5,lightintensity=2}
\def\l{1}
\multido{\r=0+0.051579}{20}{
\begin{pspicture}(-3,-3)(3,3)
\def\h{.99999 \r\space sub}
\defFunction{regulusx}(u,v){v}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Cos mul}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Sin mul}
\psSolid[object=surfaceparametree,linewidth=.1pt,base=0 2 pi mul \l\space neg \l\space,fillcolor=yellow!50,incolor=yellow!50,function=regulusx,ngrid=40 20]%    
\end{pspicture}}
\multido{\r=0+0.051579}{20}{
\begin{pspicture}(-3,-3)(3,3)
\def\h{0.01999 \r\space add}
\defFunction{regulusz}(u,v)
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Sin mul}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Cos mul}
    {v}
\psSolid[object=surfaceparametree,linewidth=.1pt,base=0 2 pi mul \l\space neg \l\space,fillcolor=yellow!50,incolor=yellow!50,function=regulusz,ngrid=40 20]%    
\end{pspicture}}
\multido{\r=0+0.051579}{20}{
\begin{pspicture}(-3,-3)(3,3)
\def\h{0.99999 \r\space sub}
\defFunction{regulusz}(u,v)
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Sin mul}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Cos mul}
    {v}
\psSolid[object=surfaceparametree,linewidth=.1pt,base=0 2 pi mul \l\space neg \l\space,fillcolor=yellow!50,incolor=yellow!50,function=regulusz,ngrid=40 20]%    
\end{pspicture}}
\multido{\r=0+0.051579}{20}{
\begin{pspicture}(-3,-3)(3,3)
\def\h{.01999 \r\space add}
\defFunction{regulusx}(u,v){v}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Cos mul}
    {1 \h\space sub v 2 exp mul 1 \h\space sub 1 \h\space add mul \h\space mul add     \h\space u Cos 2 exp mul 1 \h\space add u Sin 2 exp mul add    div   sqrt      u Sin mul}
\psSolid[object=surfaceparametree,linewidth=.1pt,base=0 2 pi mul \l\space neg \l\space,fillcolor=yellow!50,incolor=yellow!50,function=regulusx,ngrid=40 20]%    
\end{pspicture}}
\end{document}
share|improve this answer

The scientific viewpoint of an egg on the frying pan.

enter image description here

\documentclass[pstricks]{standalone}
\usepackage{pst-node,pst-plot}
\pstVerb{realtime srand}

\begin{document}
\psLoop{25}{%
\begin{pspicture}(-2,-2)(2,2)
    \pscircle*[linecolor=orange]{0.75}
    \curvepnodes[plotpoints=73]{0}{360}{Rand 10 div 1.50 add t PtoC}{P}
    \psnccurve(0,\numexpr\Pnodecount-1){P}
\end{pspicture}}
\end{document}
share|improve this answer
16  
This is a really awesome picture, especially for such simple code, but ... "scientific"? –  Charles Staats Feb 6 at 14:29
7  
For the record: I did not downvote this answer. –  Charles Staats Feb 6 at 15:03
2  
Enkelt och genialt, as the Swedes say :) –  Kuba Ober Feb 6 at 15:32
2  
@CodeMocker Next time, try to do this. –  Vÿska Feb 8 at 14:50
1  
-1: Bacon is missing. :-D –  Henri Menke Mar 6 at 7:40

Prime factorization

\documentclass{article}

\usepackage{pst-tree}
\usepackage{xintexpr}
\usepackage{siunitx}

\psset{
  levelsep=1,
  treesep=1,
  nodesep=2pt
}

\catcode`\_ 11

% This code (non-expandable) produces {{}{}{N}} followed by
% successive braced triplets {{p}{k}{m}} where p is
% a prime factor of N,  k its exponent in N, and m is
% the result of dividing N by p^k and all previous
% powers of smaller primes. So, the last triplet has m = 1.

% The code uses package xint to be able to deal
% with numbers larger than the TeX limit of 2^{31}-1
% on count registers. 

\def\factorize#1{%
    \edef\factorize_N{#1}%
    \def\factorize_exp{0}%
    \edef\factors{{{}{}{\factorize_N}}}%
    \factorize_i
}

\def\factorize_i{%
    \if\xintOdd{\factorize_N}1%
       \expandafter \factorize_ii
    \else
       \edef\factorize_exp{\xintInc{\factorize_exp}}%
       \edef\factorize_N{\xintHalf{\factorize_N}}%
       \expandafter \factorize_i
    \fi
}

\def\factorize_ii{%
    \if\xintSgn{\factorize_exp}1% 
          \edef\factors{\factors{{2}{\factorize_exp}{\factorize_N}}}%
    \fi
    \if\expandafter\XINT_isOne\expandafter{\factorize_N}1%
    \else
       \def\factorize_M{3}%
       \def\factorize_exp{0}%
       \expandafter \factorize_iii
    \fi
}

\def\factorize_iii{%
    \xintAssign\xintDivision\factorize_N\factorize_M\to
        \factorize_Q\factorize_R
    \xintSgnFork{\xintSgn\factorize_R}%
        {}%
        {\edef\factorize_exp{\xintInc{\factorize_exp}}%
         \let\factorize_N\factorize_Q 
         \factorize_iii}%
        {\factorize_iv}% 
}

 \def\factorize_iv{%
    \if\xintSgn{\factorize_exp}1%
       \edef\factors{\factors{{\factorize_M}{\factorize_exp}{\factorize_N}}}%
    \fi
    \if\expandafter\XINT_isOne\expandafter{\factorize_N}1%
    \else
       % Here N > 1, N = QM+R (0 < R < M) is < M(Q+1) and N has no
       % prime factors at most equal to M. If a prime P > M divides N, the
       % quotient N/P will be < Q+1, hence at most Q. If Q <= M, then
       % N/P must be 1 else there would be some prime <=M dividing N.
       \if\xintGeq\factorize_M\factorize_Q 1% Implies that N is prime.
          \edef\factors{\factors{{\factorize_N}{1}{1}}}% We stop here.
       \else% We go on testing with bigger factors.
          % \edef\factorize_M{\xintInc{\xintInc{\factorize_M}}}%
          \edef\factorize_M{\xintiAdd \factorize_M 2}%
          \def\factorize_exp{0}%
          \expandafter \expandafter \expandafter \factorize_iii
       \fi
    \fi
}

\catcode`\_ 8

% We now define the macro \FactorTree which will produce
% a tree displaying the factorization.

\newtoks\FactorTreeA
\newtoks\FactorTreeB

\makeatletter

\newcommand*\FactorsToTree[1]{%
    \FactorsToTree@ #1%
}

% Macro which was used to produce the images;
% variant follows which skips the exponents equal to 1.

% \newcommand*\FactorsToTree@[3]{%
%     \xintSgnFork{\xintCmp{#3}{1}}% check to see if end has been reached
%     {}%
%     {\FactorTreeA\expandafter{\the\FactorTreeA
%                               \Tcircle{$\num{#1}^{#2}$}%
%                               \TR{1}%
%                               }}%
%     {\FactorTreeA\expandafter{\the\FactorTreeA 
%                              \Tcircle{$\num{#1}^{#2}$}%
%                              \psTree{\TR{\num{#3}}}}%
%      \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}%
% }


% This variant will not print the exponents equal to 1:

\newcommand*\FactorsToTree@[3]{%
    \ifnum 0#2=1 % First triplet has an empty #2, hence the trick with 0.
       \expandafter\@firstoftwo
    \else
       \expandafter\@secondoftwo
    \fi
    % Exponent #2 is 1, so don't print it.
    {\xintSgnFork{\xintCmp{#3}{1}}% Check to see if end has been reached.
    {}%
    {\FactorTreeA\expandafter{\the\FactorTreeA
                              \Tcircle{$\num{#1}$}%
                              \TR{1}%
                              }}%
    {\FactorTreeA\expandafter{\the\FactorTreeA 
                             \Tcircle{$\num{#1}$}%
                             \psTree{\TR{\num{#3}}}}%
     \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}}
    % Exponent #2 is > 1 (or absent in the {}{}{N} triplet).
    {\xintSgnFork{\xintCmp{#3}{1}}% Check to see if end has been reached.
    {}%
    {\FactorTreeA\expandafter{\the\FactorTreeA
                              \Tcircle{$\num{#1}^{#2}$}%
                              \TR{1}%
                              }}%
    {\FactorTreeA\expandafter{\the\FactorTreeA 
                             \Tcircle{$\num{#1}^{#2}$}%
                             \psTree{\TR{\num{#3}}}}%
     \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}}%
}

\makeatletter
\def\@factorinliner #1{\@factorinliner@#1}
\def\@factorinliner@#1#2#3{%
  \ifnum #2>1 \expandafter\@firstoftwo\else
              \expandafter\@secondoftwo\fi%
  {{#1}^{#2}}{\num{#1}}%
}
\newcommand*\FactorizeInline[1]{%
  \factorize{#1}% 
  \xintListWithSep\cdot
    {\xintApply\@factorinliner{\expandafter\@gobble\factors}}%
}%

\newcommand*\FactorTree[1]{%
    \factorize{#1}%
    \FactorTreeA{\@gobbletwo}%
    \FactorTreeB{}%
    \xintApplyUnbraced\FactorsToTree{\factors}%
    \the\FactorTreeA\the\FactorTreeB
    \vspace{12ex}
    $\num{#1} = \FactorizeInline{#1}$
}

\makeatother


\begin{document}

\FactorTree{1689242184972}

\end{document}

output

share|improve this answer

I don't know the name of this illusion but the important thing is that it is about simple harmonic motion of equally-spaced points with equally-spaced phase difference. Enjoy! The same code was posted here.

enter image description here

\documentclass[preview,border=12pt,multi]{standalone}
\usepackage{pstricks}

\psset{unit=.3}

% static point
% #1 : half of the number of points
% #2 : ith point
\def\x[#1,#2]{(3*cos(Pi/#1*#2))}
\def\y[#1,#2]{(3*sin(Pi/#1*#2))}

% oscillated point
% #1 : half of the number of points
% #2 : ith point
% #3 : time parameter
\def\X[#1,#2]#3{(\x[#1,#2]*cos(#3+Pi/#1*#2))}
\def\Y[#1,#2]#3{(\y[#1,#2]*cos(#3+Pi/#1*#2))}

% single frame
% #1 : half of the number of points
% #2 : time parameter
\def\Frame#1#2{%
\begin{pspicture}(-3,-3)(3,3)
    \pstVerb{/I2P {AlgParser cvx exec} bind def}%
    \pscircle*{\dimexpr3\psunit+2pt\relax}
    \foreach \i in {1,...,#1}{\psline[linecolor=yellow](!\x[#1,\i] I2P \y[#1,\i] I2P)(!\x[#1,\i] I2P neg \y[#1,\i] I2P neg)}
    \foreach \i in {1,...,#1}{\pscircle*[linecolor=white](!\X[#1,\i]{#2} I2P \Y[#1,\i]{#2} I2P){2pt}}   
\end{pspicture}}

\begin{document}
\foreach \t in {0,...,24}
{   
    \preview
    \Frame{1}{2*Pi*\t/25} \quad \Frame{2}{2*Pi*\t/25} \quad \Frame{3}{2*Pi*\t/25} \quad \Frame{5}{2*Pi*\t/25} \quad \Frame{10}{2*Pi*\t/25}
    \endpreview
}
\end{document}
share|improve this answer

Here are two example figures produced with the Pre-/Postprocessor gmsh. gmsh has the capability to export geometries, meshes and post processing views (e.g. result of a finite element simulation) to LaTeX using pgfplots. The key feature is that axes, color map and orientation data are automatically exported. It works nicely for three-dimensional views, by automatically creating the mapping of world coordinates (x,y,z) to pixel coordinates (X,Y).

The image in the figures is still a png with a transparent layer, but the axes/labels/captions/annotations are all done with pgfplots.

Disclosure: I added this functionality myself. More info/demos.

View on a mesh of a ring shaped pipe.

Three quarters of a ring shaped pipe

\begin{tikzpicture}
\begin{axis}[
    width=.5\linewidth, % set figure width here
    enlargelimits=false, % tight axis, use xmin=<val>, xmax=<val> for custom bounding box
    grid=both,
    minor tick num=1,
    3d box,
    xlabel={x}, %
    ylabel={y},
    zlabel={z},
    zlabel style={rotate=90},
    ]
      \addplot3[surf] graphics[debug=false,%=visual,
        points={%
        (-12,-2,-12) => (750,595-341)
        (-12,8,-12) => (743,595-23)
        (-12,8,12) => (16,595-98)
        (12,-2,-12) => (1039,595-520)
        (12,-2,12)%  => (308,595-595)
        (12,8,-12)%  => (1038,595-202)
        (12,8,12)%  => (306,595-277)
        (-12,-2,12)%  => (18,595-415)
        }]
        {test-extr2.png};
\end{axis}
\end{tikzpicture}%

Example of a post processing view with automatically exported axes and color bar.

The dashed line and the dummy legend was added manually to demonstrate that drawing on top of the figure is easy. Everything else was created automatically.

Post processing view

\pgfplotsset{
colormap={gmshcolormap}{% note: Only needed once if colorbars do not change
rgb255=(0,12,92) rgb255=(0,7,98) rgb255=(9,3,103) rgb255=(19,0,107) rgb255=(30,0,110) rgb255=(40,0,112) rgb255=(50,0,113) rgb255=(60,0,114) rgb255=(70,0,114) rgb255=(79,0,114) rgb255=(88,0,113) rgb255=(97,0,111) rgb255=(105,1,109) rgb255=(114,4,107) rgb255=(122,8,104) rgb255=(130,12,100) rgb255=(137,16,97) rgb255=(145,21,93) rgb255=(152,26,88) rgb255=(159,31,84) rgb255=(166,37,79) rgb255=(174,45,73) rgb255=(180,51,68) rgb255=(186,58,63) rgb255=(192,65,58) rgb255=(198,72,53) rgb255=(203,80,48) rgb255=(208,87,43) rgb255=(213,95,38) rgb255=(218,102,33) rgb255=(222,110,29) rgb255=(226,118,25) rgb255=(230,126,21) rgb255=(234,133,17) rgb255=(237,141,14) rgb255=(241,149,11) rgb255=(244,157,9) rgb255=(246,164,7) rgb255=(249,172,6) rgb255=(251,179,5) rgb255=(254,186,5) rgb255=(255,193,5) rgb255=(255,202,7) rgb255=(255,208,9) rgb255=(255,214,11) rgb255=(255,220,15) rgb255=(255,226,19) rgb255=(255,231,25) rgb255=(255,236,31) rgb255=(255,240,38) rgb255=(255,244,46) rgb255=(255,248,55) rgb255=(255,251,66) rgb255=(255,254,77) rgb255=(255,255,90) rgb255=(255,255,103) rgb255=(255,255,118) rgb255=(255,255,134) rgb255=(254,255,152) rgb255=(252,255,171) rgb255=(249,255,191) rgb255=(247,254,213) rgb255=(244,251,236) rgb255=(241,247,255) }
}%
\begin{tikzpicture}
\begin{axis}[
    width=.5\linewidth, % set figure width here
    enlargelimits=false, % tight axis, use xmin=<val>, xmax=<val> for custom bounding box
    xlabel={x}, % if you rotated your view, adjust these labels!
    ylabel={y},
    scale only axis,
    axis equal image, % use png aspect ratio
    axis on top,
    title={Electric Field Intensity / (V/m)},
    colorbar,
    scaled ticks=false,
    colormap name=gmshcolormap,
    colorbar right, %or left...
    colorbar style={
            %width=0.5cm, % adjust width of colorbar
            %height=6cm,% adjust height of colorbar,
    }]
      % a dummy plot for the colorbar (invisible):
      \addplot[point meta min=0.000000, point meta max=359, update limits=false, 
            draw=none, colorbar source, forget plot]
      coordinates{(1,1)};
      \addplot[surf,point meta min=0, point meta max=359] 
            graphics[xmin=0, xmax=0.05, ymin=0, ymax=0.05]
        {cycl.png};
        \label{pgfplots:surf}
      \addlegendentry{foo $\Phi_x^2$}
      \addplot[black,densely dashed,ultra thick,
         update limits=false,domain=0:0.05,samples=100] {-0.5*x+0.025+0.01*sin(10000*x)};
        \label{pgfplots:dummy}
      \addlegendentry{bar $|\langle \varphi \rangle^2|_\infty$}
\end{axis}
\end{tikzpicture}%
share|improve this answer

This is one I like from my thesis. It illustrates the predicted boundaries for boundary layer transition mechanisms on a cylindrical afterbody at incidence: (1) free shear-layer instability, (2) attachment-line instability, (3) cross-flow instability, (4) streamwise-flow instability.

enter image description here

\documentclass{standalone}
\usepackage{calc,pgfplots}
      \pgfplotsset{compat=1.7}

\begin{document}

%% free shear-layer instability (fsli)
\pgfmathdeclarefunction{fsli}{1}{%
  \pgfmathparse{ tan(#1)/( cos(#1)*( 1 + 3.3*((tan(#1))^2) ) ) }%
}%
%
%% attachment-line instability (ali)
\pgfmathdeclarefunction{ali}{1}{%
  \pgfmathparse{ 1.1*tan(#1)*(1/cos(#1)) }%
}%
%
%% cross-flow instability (csi)
\pgfmathdeclarefunction{csi}{1}{%
  \pgfmathparse{ 0.145*( ( 1 + 3.3*(tan(#1))^2 ) / sin(#1) ) }%
}%
%
%% streamwise-flow instability (sfi)
\pgfmathdeclarefunction{sfi}{1}{%
  \pgfmathparse{ 4 }%
}%
%
%% piecewise function (combining ali, csi and sfi)
\pgfmathdeclarefunction{alicsisfi}{1}{%
  \pgfmathparse{%
    (and( #1>=1    , #1<=25.78) * ( ali(x) ) +%
    (and( #1>25.78 , #1<=70.00) * ( csi(x) ) +%
                (and( #1>70.00 , #1<=89.99) * ( sfi(x) )  %
   }%
}%



\begin{tikzpicture}

% set style options for annotations with pins (see bottom of tikzpicture)
\tikzset{%
   every pin/.style={draw=none,
                     fill=none,
                     %rectangle,rounded corners=0pt,
                     font=\scriptsize}
                 }

\begin{semilogyaxis}[%
%
view={0}{90},
width=0.50\linewidth,height=0.75\linewidth,
%
scale only axis,
axis on top=false,
axis lines*=box,
%
xmin=0, xmax=90,
xtick={0,10,20,30,40,50,60,70,80,90},
xlabel={\raisebox{0pt}[\height][\depth]{$\alpha$ (deg)}},
%
ymin=0.1, ymax=10,
ytick={0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,2,3,4,5,6,7,8,9,10},
yticklabels={0.1,0.2,{},0.4,{},0.6,{},0.8,{},1.0,2,{},4,{},6,{},8,{},10},
ylabel={\raisebox{0pt}[\height][\depth]{$R_D \times 10^{6}$}},
]



%% fsli (start stacking)
\addplot[
domain=1:89.99,samples=225,
draw=none,fill=none,mark=none,
stack plots=y]
{ fsli(x) };
%
%% stack difference between alicsisfi (upper) and fsli (lower) curves on top of fsli and fill area
\addplot[
domain=1:89.99,samples=225,
draw=none,
fill=black!10,
stack plots=y]
{ max( alicsisfi(x) - fsli(x) , 0 ) } % area above fsli and below alicsisfi
\closedcycle;



%% fsli, alpha = [1 , 89.99]
\addplot[
domain=1:89.99,samples=225,
solid,line width=0.8pt,draw=black,mark=none]
{ fsli(x) };



%% ali (1), alpha = [1 , 25.78]
\addplot[
domain=1:25.78,samples=62,
solid,line width=0.8pt,draw=black,mark=none]
{ ali(x) };
%
%% ali (2), alpha = [25.78 , 89.99]
\addplot[
domain=25.78:89.99,samples=163,
dashed,draw=black,mark=none]
{ ali(x) };



%% csi (1), alpha = [1 , 25.78]
\addplot[
domain=1:89.99,samples=62,
dashed,draw=black,mark=none]
{ csi(x) };
%
%% csi (2), alpha = [25.78 , 70]
\addplot[
domain=25.78:70,samples=112,
solid,line width=0.8pt,draw=black,mark=none]
{ csi(x) };
%
%% csi (3), alpha = [70 , 89.99]
\addplot[
domain=70:89.99,samples=174,
dashed,draw=black,mark=none]
{ csi(x) };



%% sfi (1), alpha = [1 , 70]
\addplot[
domain=1:70,samples=350,
dashed,draw=black,mark=none]
{ sfi(x) };
%
%% sfi (2), alpha = [70 , 89.99]
\addplot[
domain=70:89.99,samples=51,
solid,line width=0.8pt,draw=black,mark=none]
{ sfi(x) };


%% annotations (see style options for pins set with \tikzset above)
\node[coordinate,pin=-95:{1}] at (axis cs:50,0.326) {};
\node[coordinate,pin=-30:{2}] at (axis cs:23.3,0.5158) {};
\node[coordinate,pin=below right:{3}] at (axis cs:52.3,1.196) {};
\node[coordinate,pin=80:{4}] at (axis cs:77.5,4) {};
%
\node[draw=black,fill=white] at (axis cs:47,0.16) {\emph{laminar regime}};
\node[draw=black,fill=white] at (axis cs:60,0.52) {\emph{short bubble regime}};
\node[draw=black,fill=white] at (axis cs:30,3.95) {\emph{turbulent regime}};

\end{semilogyaxis}

\end{tikzpicture}

\end{document}
share|improve this answer

The butterfly curve.

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

\DIVIDE{1}{12}{\invXII}
\MULTIPLY{12}{\numberTWOPI}{\phione}  
\MULTIPLY{12}{64}{\divisions}  

\COMPOSITIONfunction{\EXPfunction}{\COSfunction}{\Afunction}
\SCALEVARIABLEfunction{4}{\COSfunction}{\Bfunction}
\SCALEVARIABLEfunction{\invXII}{\SINfunction}{\cfunction}
\POWERfunction{\cfunction}{5}{\Cfunction}
\LINEARCOMBINATIONfunction{1}{\Afunction}{-2}{\Bfunction}{\ABfunction}
\SUBTRACTfunction{\ABfunction}{\Cfunction}{\ABCfunction}
\PRODUCTfunction{\SINfunction}{\ABCfunction}{\Xfunction}
                % x=(sin t)(exp(cos t)-2 cos 4t + (sin(t/12))^5)
\PRODUCTfunction{\COSfunction}{\ABCfunction}{\Yfunction}     
                % y=(cos t)(exp(cos t)-2 cos 4t + (sin(t/12))^5)
\PARAMETRICfunction{\Xfunction}{\Yfunction}{\butterfly}

\setlength{\unitlength}{1cm}

\centering
\begin{Picture}(-4,-3)(4,4)
    \PlotParametricFunction[\divisions]\butterfly{0}{\phione}   
\end{Picture}
\[
  \mathbf{f}(t)=
     \left(\mathrm{e}^{\cos t}-2\cos 4t+\sin^5 \frac{t}{12}\right)
     (\sin t,\cos t)
\]

\end{document}

The butterfly curve

share|improve this answer

Lifting of a random Delaunay triangulation to a hyperbolic paraboloid:

  1. The planar delaunay triangulation was generated using C++ and CGAL
  2. The data was visualized using asymptote

enter image description here

Here is the c++ code:

#include <fstream>
#include <sstream>
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Delaunay_triangulation_2.h>

using namespace CGAL;

typedef Exact_predicates_inexact_constructions_kernel   K;

typedef Delaunay_triangulation_2<K>                       Triangulation;
typedef Triangulation::Edge_iterator                        Edge_iterator;
typedef Triangulation::Point                                  Point;
typedef Triangulation::Vertex_handle                        Vertex;
typedef Triangulation::Face                                 Face;

typedef Creator_uniform_2<double,Point>         Creator;
typedef std::vector<Point>                        Point_set;
typedef std::vector<std::string>            Edges_str;

int main () {
  int numPts = 50;
  Point_set points;
  points.reserve(numPts);

  Random_points_in_disc_2<Point, Creator> randomGen (1.0 );
  cpp0x::copy_n( randomGen, numPts, std::back_inserter(points));

  Triangulation dt;
  dt.insert(points.begin(),points.end());

  int num_of_edges = 0;

  Edges_str edges_str;
  Edge_iterator eit;
  for (eit = dt.finite_edges_begin(); eit != dt.finite_edges_end(); ++eit)
    {
      ++num_of_edges;
      std::ostringstream strs;
      Triangulation::Face& f = *(eit->first);
      int i = eit->second;
      Vertex vs = f.vertex(f.cw(i));
      Vertex vt = f.vertex(f.ccw(i));
      strs << vs->point().x();
      std::string vsx = strs.str();
      strs.str("");
      strs.clear();
      strs << vs->point().y();
      std::string vsy = strs.str();
      strs.str("");
      strs.clear();
      strs << vt->point().x();
      std::string vtx = strs.str();
      strs.str("");
      strs.clear();
      strs << vt->point().y();
      std::string vty = strs.str();

      std::string curr_edge = "("+vsx+","+vsy+")\n"+"("+vtx+","+vty+")\n";
      edges_str.push_back(curr_edge);
    }

  std::ofstream out("random-delaunay-of-saddle.dat");
  out << num_of_edges << "\n";
  for (Edges_str::iterator it = edges_str.begin(); it != edges_str.end() ; ++it)
    out << *it;
  out.close();
  return 0;
}

that produces the random Delaunay triangulation in the plane. The generated file random-delaunay-of-saddle.dat is used by the following asymptote code,

import graph3;
size(400);

surface operator cast(tube t) {
  return t.s;
}

currentprojection=perspective(0.75,1.2,0.2);
real gridWidth=1.5;
pen  gridPen=blue;

real xy_level=-2.1;

real f (pair p){
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);
}

struct Edge {
  pair source; // Source point
  pair target; // Target point
}

struct Edge3D {
  triple source; // Source point
  triple target; // Target point
}

// Read 2D points from file
file fin=input("random-delaunay-of-saddle.dat");
int num_of_edges = fin;
write(num_of_edges);
Edge[] edges;
pair p1,p2;
for (int i=0; i<num_of_edges; ++i){
  p1=fin;
  p2=fin;
  Edge e;
  // Scaling the points, so the surface will be compatible with the non
  // approximated one
  e.source=2*p1;
  e.target=2*p2;
  edges.push(e);
}

Edge3D[] floorEdges,saddleEdges;

for (int i=0 ; i<num_of_edges; ++i){
  pair source=edges[i].source;
  real psx=source.x;
  real psy=source.y;
  pair target=edges[i].target;
  real ptx=target.x;
  real pty=target.y;

  triple Source1=(psx,psy,xy_level);
  triple Target1=(ptx,pty,xy_level);
  Edge3D e1;
  e1.source=Source1;
  e1.target=Target1;
  floorEdges.push(e1);

  triple Source2=(psx,psy,f((source.x,source.y)));
  triple Target2=(ptx,pty,f((target.x,target.y)));
  Edge3D e2;
  e2.source=Source2;
  e2.target=Target2;
  saddleEdges.push(e2);
}

for (int i=0; i<num_of_edges; ++i){
  draw(tube(floorEdges[i].source--floorEdges[i].target,0.02*gridWidth),darkgreen);
  draw(tube(saddleEdges[i].source--saddleEdges[i].target,0.02*gridWidth),darkgreen);
}

real minVal = -2;
real maxVal = -minVal;

surface saddle=surface(f,(minVal,minVal),(maxVal,maxVal),nx=6,Spline);
draw(saddle,gray+opacity(0.75));

surface plane=surface(
                      new triple(pair p) {
                        return (p.x,p.y,xy_level);
                      },(1.2*minVal,1.2*minVal),(1.2*maxVal,1.2*maxVal)
                      );
draw(plane,gray+opacity(0.3));

to generate the image.

share|improve this answer

Here is a plot of the log barrier function B(x1, x2) = -ln x1 - ln x2.

enter image description here

Code (python to generate the lattice):

from numpy import linspace, pi, sin, cos, log
from scipy.optimize import bisect

# Code to generate patches
# (x(r,theta), y(r,theta), z(r,theta)), where
#    x(r,theta) = 1 - r cos(theta), 
#    y(r,theta) = 1 - r sin(theta), 
#    z(r,theta) = -log(x(r,theta)) - log(y(r,theta)).

PATCH = [(0,0), (2,0), (2,2), (0,2), (1,0), (2,1), (1,2), (0,1), (1,1)]
N     = 23
zmax  = 6
zmin  = -log(1)-log(1)

# Determine the value such that z = -log(x(r,theta)) - log(y(r,theta)).
def zinv(theta, z):
  f = lambda r: -log(1 - r*cos(theta)) - log(1 - r*sin(theta)) - z
  maxr = min(1/cos(theta), 1/sin(theta)) - 1e-6
  return bisect(f, 0, maxr)

P = dict()
V = []

# Generate lattice points
for i, theta in enumerate(linspace(1e-6, pi/2-1e-6, N)):
  for j, z in enumerate(linspace(zmin, zmax, N)):
     r = zinv(theta, z)
     x = 1 - r * cos(theta)
     y = 1 - r * sin(theta)
     z = - log(x) - log(y)
     P[i,j] = len(V)
     V.append((x,y,z))

# Write vertices
vfile = open("logbarrier_v.txt", "wt")
for v in V:
  vfile.write("%0.8f %0.8f %0.8f\n" % v)
vfile.close()

# Write patches
pfile = open("logbarrier_p.txt", "wt")
for j in range(0, N-1, 2):
  for i in range(0, N-1, 2):
    for (di, dj) in PATCH:
       pfile.write(str(P[i+di,j+dj]) + " ")
    pfile.write("\n")
pfile.close()

and LaTeX:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8} 
\usepgfplotslibrary{patchplots}

\definecolor{plotfill}{RGB}{215,227,244}
\definecolor{plotblue}{RGB}{60,120,200}

\begin{document}
\begin{tikzpicture}
\begin{axis}[xmin=0, xmax=1.2, ymin=0, ymax=1.4, zmin=0, zmax=6, 
             axis y line=center, axis x line=center, axis z line=center,
             view/h=70, xtick={0, 1}, ytick={0}, ztick={0,5}, 
             clip=false, axis on top=false, axis line style=thick, every tick/.style={black, thick}]

\node at (rel axis cs:1,0,0) [above, anchor=north west] {$x_1$};  %sloped like x axis, 
\node at (rel axis cs:0,1,0) [above, anchor=west] {$x_2$};
\node at (rel axis cs:0,0,1) [above, anchor=south] {$B(x_1,x_2)$};


\addplot3 [patch,patch type=biquadratic,shader=faceted interp,samples=5,draw=black, draw opacity=0.8,opacity=0.8,z buffer=sort,
   patch table=logbarrier_p.txt,colormap={custom}{color(0)=(plotfill) color(4)=(plotblue)}]
file {logbarrier_v.txt}; 

\addplot3 [patch,patch type=biquadratic,mesh,draw=black, draw opacity=0.05,z buffer=sort,
   patch table=logbarrier_p.txt]
file {logbarrier_v.txt}; 


\draw [dashed] (axis cs: 1, 0, 0) -- (axis cs: 1, 1, 0);
\draw [dashed, opacity=0.33] (axis cs: 1, 1, 0) -- (axis cs: 0, 1, 0);
\draw [dashed, thick, opacity=0.33] (axis cs: 0, 0.2, 0) -- (axis cs: 0, 1.3, 0);
\draw [thick, opacity=0.33] (axis cs: 0, 1, 0.15) -- (axis cs: 0, 1, -0.15);
\node at (axis cs: 0, 1, 0) [anchor=south, opacity=0.33] {$1$};
\node at (axis cs: 0, 0, 0) [anchor=east] {$\mathbf{0}$};
\end{axis}
\end{tikzpicture}

\end{document}
share|improve this answer
3  
BTW: For anyone interested, I just learned that you can enable syntax highlighting to non-LaTeX code on stackexchange by adding e.g. <!-- language: lang-python --> in front of python code (see my post). –  Yori Feb 18 at 8:48

Below I made a basic diagram to illustrate (vertical) interlinkages such as in a supply chain in an economy.

\documentclass{article}
\usepackage{tikz}
\begin{document} 
\begin{tikzpicture}
\draw (0,0) -- (6,0);
\draw (0,0) -- (0,-1); \draw (6,0) -- (6,-1);
\draw (0,0) rectangle (1,-1);
\draw (1,0) rectangle (2,-1);
\draw (2,0) rectangle (3,-1);
\draw (3,0) rectangle (4,-1);
\draw (4,0) rectangle (5,-1);
\draw (5,0) rectangle (6,-1);
\draw [yellow, line width=6] (0,-1)--(1,-1);
\draw [red, line width=6] (1,-1)--(2,-1);
\draw [green, line width=6] (2,-1)--(3,-1);
\draw [pink, line width=6] (3,-1)--(4,-1);
\draw [purple, line width=6] (4,-1)--(5,-1);
\draw [lightgray, line width=6] (5,-1)--(6,-1);
\draw[<->,thick,cyan] (0.5,-1.5) to [out=305,in=225] (1.5,-1.5); 
\draw[<->,thick,cyan] (1.5,-1.5) to [out=305,in=225] (2.5,-1.5);
\draw[<->,thick,cyan] (2.5,-1.5) to [out=305,in=225] (3.5,-1.5);
\draw[<->,thick,cyan] (3.5,-1.5) to [out=305,in=225] (4.5,-1.5);
\draw[<->,thick,cyan] (4.5,-1.5) to [out=305,in=225] (5.5,-1.5);
\node at (0.5,0.3) {I};
\node at (1.5,0.3) {II};
\node at (2.5,0.3) {III};
\node at (3.5,0.3) {IV};
\node at (4.5,0.3) {V};
\node at (5.5,0.3) {VI};
\end{tikzpicture}
\end{document} 

enter image description here

share|improve this answer

Galvanic cell

\documentclass{article}

\usepackage[
  figureposition = bottom
]{caption}
\usepackage{chemmacros}
\usepackage{pstricks-add}

\makeatletter
  \providecommand*{\setfloatlocations}[2]{\@namedef{fps@#1}{#2}}
\makeatother
\setfloatlocations{figure}{htbp}

\DeclareCaptionLabelSeparator{adjustment}{:\quad}
\captionsetup{
  font = small,
  labelfont = sc,
  labelsep = adjustment
}

\def\anode{\ch{Zn}}
\def\anodeColour{gray!30}
\def\cathode{\ch{Cu}}
\def\cathodeColour{red!50}

\makeatletter
 \define@key{cell}{anode}{\def\anode{\ch{#1}}}
 \define@key{cell}{anodeColour}{\def\anodeColour{#1}}
 \define@key{cell}{cathode}{\def\cathode{\ch{#1}}}
 \define@key{cell}{cathodeColour}{\def\cathodeColour{#1}}
\makeatother

\newcommand*\cell[4][]{%
  \setkeys{cell}{#1}
  \def\basinWidth{#2 }
  \def\basinHeight{#3 }
  \def\waterHeight{#4}
% Basin
\psline(0,\basinHeight)(0,\waterHeight)
\pscustom[
  fillstyle=solid,
  fillcolor=cyan!70
]{%
  \psline(0,\waterHeight)(\basinWidth,\waterHeight)
  \psline(0,\waterHeight)(0,1)
  \psarc(1,1){1}{180}{270}
  \psline(1,0)(!\basinWidth 1 sub 0)
  \psarc(!\basinWidth 1 sub 1){1}{270}{360}
  \psline(\basinWidth,1)(\basinWidth,\waterHeight)
 \closepath
}
\psline(\basinWidth,\waterHeight)(\basinWidth,\basinHeight)
% Membrane
\psline[
  linestyle=dashed
](!\basinWidth 2 div 0)%
 (!\basinWidth 2 div \waterHeight)
% Cathode
\pspolygon[
  fillstyle=solid,
  fillcolor=\cathodeColour
](!\basinWidth 4 div 1 sub 1)%
 (!\basinWidth 4 div 1 sub \basinHeight 1 sub)%
 (!\basinWidth 4 div 1 add \basinHeight 1 sub)%
 (!\basinWidth 4 div 1 add 1)
\rput(!\basinWidth 4 div \basinHeight 2 div){\cathode\xspace}
% Anode
\pspolygon[
  fillstyle=solid,
  fillcolor=\anodeColour
](!3 \basinWidth mul 4 div 1 sub 1)%
 (!3 \basinWidth mul 4 div 1 sub \basinHeight 1 sub)%
 (!3 \basinWidth mul 4 div 1 add \basinHeight 1 sub)%
 (!3 \basinWidth mul 4 div 1 add 1)
\rput(!3 \basinWidth mul 4 div \basinHeight 2 div){\anode}
% Wires with current
\rput(!\basinWidth 4 div 1 add \basinHeight){$+$}
\psline(!\basinWidth 4 div \basinHeight 1 sub)%
       (!\basinWidth 4 div \basinHeight)
\psarc(!\basinWidth 4 div 1 add \basinHeight){1}{90}{180}
\psline(!\basinWidth 4 div 1 add \basinHeight 1 add)%
       (!\basinWidth 1 sub 2 div \basinHeight 1 add)
\pscircle(!\basinWidth 2 div \basinHeight 1 add){0.5}
\rput(!\basinWidth 2 div \basinHeight 1 add){$U$}
\psline(!3 \basinWidth mul 4 div 1 sub \basinHeight 1 add)%
       (!\basinWidth 1 add 2 div \basinHeight 1 add)
\psarc(!3 \basinWidth mul 4 div 1 sub \basinHeight){1}{0}{90}
\psline(!3 \basinWidth mul 4 div \basinHeight 1 sub)%
       (!3 \basinWidth mul 4 div \basinHeight)
\rput(!3 \basinWidth mul 4 div 1 sub \basinHeight){$-$}
% Electron movement
\rput(!3 \basinWidth mul 1 add 8 div \basinHeight 3 2 div add)%
     {\ch{<-[$\el$]}}
\rput(!5 \basinWidth mul 2 sub 8 div \basinHeight 3 2 div add)%
     {\ch{<-[$\el$]}}
}

\psset{unit = 0.5\psunit}


\begin{document}

% Without optional arguments; the `stardard' version.
\begin{figure}
 \centering
  \begin{pspicture}(15,11.9)
    \cell{15}{10}{8}
  \end{pspicture}
 \caption{Galvanic cell where \anode{} is the anode and \cathode{} is the cathode.}
\end{figure}

% With optional arguments; a `non-stardard' version.
\begin{figure}
 \centering
  \begin{pspicture}(15,11.9)
    \cell[
      anode = Cu,
      anodeColour = red!50,
      cathode = Ag,
      cathodeColour = gray!20
    ]{15}{10}{8}
  \end{pspicture}
 \caption{Galvanic cell where \ch{Cu} is the anode and \ch{Ag} is the cathode.}
\end{figure}

\end{document}

output

share|improve this answer

Thanks to this question y was able to do something I wanted to do a long time ago: the shape of pi with the digits of pi.

The only "hard" thing is the shape, but looking at the question I said it's pretty simple.

\documentclass[10pt]{article}

\usepackage{graphicx}   
\usepackage{shapepar}
\usepackage{microtype}

\def\pipar#1{\shapepar{\pishape}#1\par}
\def\pishape{%
{25.0839}%
{0.0838926}b{14.3456}\\%
{0.0838926}t{14.3456}{33.3054}\\%
{0.503356}t{11.5772}{37.6678}\\%
{1.25839}t{9.98322}{39.6812}\\%
{2.09732}t{8.52614}{41.5578}\\%
{2.85235}t{7.21477}{42.8691}\\%
{3.27181}t{6.7953}{43.2886}\\%
{4.11074}t{5.95638}{43.7081}\\%
{5.28524}t{4.78188}{43.7081}\\%
{5.62081}t{4.44631}{15.1007}st{19.547}{12.6678}st{32.2148}{15.0168}\\%
{5.62081}t{4.44631}{7.9698}t{19.547}{2.34899}t{32.2148}{2.34899}\\%
{6.04027}t{4.18011}{6.22257}t{19.4227}{2.37488}t{32.1424}{2.37047}\\%
{6.87919}t{3.64772}{5.16101}t{19.1741}{2.42667}t{31.9978}{2.41343}\\%
{7.63423}t{3.16856}{4.04621}t{18.9504}{2.47328}t{31.8676}{2.45208}\\%
{8.05369}t{2.90236}{3.80463}t{18.8261}{2.49917}t{31.7953}{2.47356}\\%
{8.38926}t{2.6894}{3.61137}t{18.7267}{2.51989}t{31.7245}{2.50373}\\%
{9.22819}t{2.15701}{3.12823}t{18.4781}{2.57167}t{31.5474}{2.57045}\\%
{9.98322}t{1.67785}{2.96021}t{18.2544}{2.61828}t{31.388}{2.6305}\\%
{11.5772}t{0.415968}{2.85584}t{17.7821}{2.71667}t{31.0515}{2.75727}\\%
{11.9966}t{0.0838926}{2.91826}t{17.6578}{2.74256}t{30.9629}{2.79063}\\%
{12.4161}t{0.0838926}{2.64861}t{17.5336}{2.76846}t{30.8743}{2.82399}\\%
{12.7517}t{0.0838926}{2.43289}t{17.4088}{2.81003}t{30.8035}{2.85068}\\%
{13.1711}t{0.0838926}{2.22315}t{17.2529}{2.862}t{30.715}{2.88404}\\%
{13.5906}t{0.0838926}{2.01342}t{17.097}{2.91397}t{30.6264}{2.9174}\\%
{14.0101}t{0.0838926}{0.838926}t{16.9411}{2.96594}t{30.5378}{2.95076}\\%
{14.0101}e{0.922819}t{16.9411}{2.96594}t{30.5378}{2.95076}\\%
{14.7651}t{16.6605}{3.05948}t{30.3785}{3.01081}\\%
{15.604}t{16.3487}{3.16342}t{30.2013}{3.18792}\\%
{16.7785}t{15.9121}{3.30893}t{30.0039}{3.3854}\\%
{21.896}t{14.0101}{3.94295}t{29.1434}{4.24586}\\%
{25.0839}t{12.7724}{4.3305}t{28.6074}{4.78188}\\%
{25.8389}t{12.4793}{4.42229}t{28.6074}{4.78188}\\%
{29.0268}t{11.2416}{4.80984}t{28.6074}{5.39494}\\%
{29.4463}t{11.0415}{4.8981}t{28.6074}{5.47561}\\%
{30.2013}t{10.6813}{5.04094}t{28.6074}{5.62081}\\%
{30.6208}t{10.4812}{5.12029}t{28.6074}{5.72383}\\%
{34.9832}t{8.40004}{5.9456}t{28.9901}{6.41263}\\%
{35.4027}t{8.19993}{6.00914}t{29.0268}{6.58557}\\%
{37.3322}t{7.27942}{6.30143}t{29.5346}{7.04256}\\%
{38.1711}t{6.87919}{6.42852}t{29.7554}{6.64702}\\%
{38.5906}t{6.87919}{6.29195}t{29.8658}{6.44925}\\%
{39.3456}t{7.09492}{5.59084}t{30.1612}{5.9965}\\%
{39.7651}t{7.21477}{5.20134}t{30.3254}{5.4129}\\%
{40.5201}t{7.63423}{4.24257}t{30.6208}{4.36242}\\%
{40.9396}t{8.01175}{3.56544}t{31.2081}{2.60067}\\%
{41.3591}t{8.38926}{2.43289}t{31.7953}{0.838926}\\%
{41.3591}e{10.8221}e{32.6342}%
}

\begin{document}

\pipar{3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 1 6 9 3 9 9 3 7 5 1 0 5 8 2 0 9 7 4 9 4 4 5 9 2 3 0 7 8 1 6 4 0 6 2 8 6  2 0 8 9 9 8 6 2 8 0 3 4 8 2 5 3 4 2 1 1 7 0 6 7 9 8 2 1 4 8 0 8 6 5 1 3 2 8 2 3 0 6 6 4 7 0 9 3 8 4 4 6 0 9 5 5 0 5 8 2 2 3 1 7 2 5 3 5 9 4 0 8 1 2 8 4 8 1  1 1 7 4 5 0 2 8 4 1 0 2 7 0 1 9 3 8 5 2 1 1 0 5 5 5 9 6 4 4 6 2 2 9 4 8 9 5 4 9 3 0 3 8 1 9 6 4 4 2 8 8 1 0 9 7 5 6 6 5 9 3 3 4 4 6 1 2 8 4 7 5 6 4 8 2 3 3  7 8 6 7 8 3 1 6 5 2 7 1 2 0 1 9 0 9 1 4 5 6 4 8 5 6 6 9 2 3 4 6 0 3 4 8 6 1 0 4 5 4 3 2 6 6 4 8 2 1 3 3 9 3 6 0 7 2 6 0 2 4 9 1 4 1 2 7 3 7 2 4 5 8 7 0 0 6  6 0 6 3 1 5 5 8 8 1 7 4 8 8 1 5 2 0 9 2 0 9 6 2 8 2 9 2 5 4 0 9 1 7 1 5 3 6 4 3 6 7 8 9 2 5 9 0 3 6 0 0 1 1 3 3 0 5 3 0 5 4 8 8 2 0 4 6 6 5 2 1 3 8 4 1 4 6  9 5 1 9 4 1 5 1 1 6 0 9 4 3 3 0 5 7 2 7 0 3 6 5 7 5 9 5 9 1 9 5 3 0 9 2 1 8 6 1 1 7 3 8 1 9 3 2 6 1 1 7 9 3 1 0 5 1 1 8 5 4 8 0 7 4 4 6 2 3 7 9 9 6 2 7 4 9  5 6 7 3 5 1 8 8 5 7 5 2 7 2 4 8 9 1 2 2 7 9 3 8 1 8 3 0 1 1 9 4 9 1}

\end{document}

enter image description here

share|improve this answer
1  
The question is for scientific pictures. Though your code is awesome, it does not fit here IMHO. I suggest you to add this to e.g. Showcase TeX Typography for TUG's Calendar instead. –  Speravir Feb 15 at 18:19
4  
And how about sending a pishape.def to the maintainer of shapepar? –  Speravir Feb 15 at 18:37

Edit: Oops, realized too late this was about images drawn using latex.

Typing up a conference paper for ICGG 2014 in Innsbruck about phase spaces and fitness landscapes. Although I'm a programmer for a 3D CAD company, I've grown very tired of rendered images as of late. I find it very difficult to draw focus to specific salient details in a digital image.

Although I heavily rely on 3D software and custom programming to generate the geometry in these images, everything is ultimately hand-drawn. Labels are added directly in LaTeX using \put commands, so the images are kept clean.

enter image description here

enter image description here

enter image description here

enter image description here

Not sure what anyone is going to learn from the code, but here is the tex for the bottommost image:

\begin{figure}[H] \centering
\begin{overpic}[width=.95\linewidth]{Images/OverconstrainedLandscape}
 \put (40,15) {\smaller[2] $\nicecirc{1}$}
 \put (66,35) {\smaller[2] $\nicecirc{1}$}
 \put (3,46)  {\smaller[2] $\nicecirc{2}$}
 \put (45,55) {$\pazocal{L}^\prime$}
\end{overpic}
\caption{Geometry of overconstrainedness}
\label{fig:overconstrainedlandscape}
\end{figure}
share|improve this answer
2  
This does not really answer the question, because the question is interested in graphics that were actually created in LaTeX, and not included from image files. Also please post an image of the result of the included code. –  marczellm Feb 11 at 21:49
3  
Very nice pictures. It would be great if we could draw such pictures in LaTeX:-) –  Marc van Dongen Feb 14 at 12:26
1  
Very Penrose-like pictures! –  Andrestand Feb 15 at 16:58
2  
@MarcvanDongen now there's a challenge... –  Thruston Mar 21 at 0:07

Visualisation of the Poincaré disk model:

\documentclass[a4paper,fleqn,papersize]{jsarticle}
\usepackage{graphicx}
\usepackage{MePoTeX}
\usepackage{amsmath,amssymb}
\usepackage{mtcastle}
\usepackage{ascmac}
\usepackage{eclarith,qbgraph}
\setlength{\columnseprule}{0.2pt}
\setlength{\textwidth}{190truemm}
\setlength{\textheight}{257truemm}
\setlength{\oddsidemargin}{-15truemm}
\setlength{\topmargin}{-15truemm}
\setlength{\headheight}{0mm}
\setlength{\headsep}{0mm}
\setlength{\fboxrule}{0.2pt}
%------------------------------------------------------------------------
\title{Poincare Disc}
\author{Moonlight Satie}
\begin{document}
%------------------------------------------------------------------------
\maketitle
%------------------------------------------------------------------------
%------------------------------------------------------------------------
\hspace{-4mm}
\begin{MPpic}<96mm>(2,2)(-1,-1)%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\sendMP{%================================================================
fill fullcircle scaled 2w withcolor 0.5white;
draw fullcircle scaled 2w;
numeric m,n;
m:=4;n:=5;
%-------------------------------------------------------------------
numeric ta,tb,ca,sa,cb,sb,cab,sab,tmpa,tmpb,k;
ta:=180/m;tb:=180/n;
ca:=cosd(ta);sa:=sind(ta);cb:=cosd(tb);sb:=sind(tb);
sab:=sa*cb+ca*sb;cab:=ca*cb-sa*sb;
tmpa:=(sb+sa/cab)/sab;tmpb:=sa/cab;
k:=1/(tmpa+-+tmpb);
}%=======================================================================
\sendMP{%================================================================
def poiP(expr p,r,x)=%----------------------------------------------
p+(x-p)/length(x-p)/length(x-p)*r*r;
enddef;%------------------------------------------------------------
def fidraw(expr p,c)=%----------------------------------------------
fill p scaled w withcolor c;
draw p scaled w;
enddef;%------------------------------------------------------------
def centPoiT(expr X,Y,Z)=%----------------------------------------------
if abs(angle(X)-angle(Y))>1:
whatever[(X+Y)/2,(X+Y)/2+(X-Y) rotated 90]=%
whatever[(X+Z)/2,(X+Z)/2+(X-Z) rotated 90];%
else:(0,0);fi;
enddef;%------------------------------------------------------------
def centPoi(expr X,Y)=%----------------------------------------------
if X=(0,0):(0,0);
elseif Y=(0,0):(0,0);
else:centPoiT(X,Y,X/(length(X)**2));fi;
enddef;%------------------------------------------------------------
def angleChk(expr X,Y)=%-------------------------------------------------
if angle(X)<angle(Y):true;else:false;fi;
enddef;%------------------------------------------------------------
def arcPoi(expr X,Y,R)=%----------------------------------------------
if length(R)<1:X--Y;
elseif X=O:X--Y;
elseif Y=O:X--Y;
elseif angle(X)<angle(Y):
if angle(Y)-angle(X)<180:X{dir (angle(X-R)-90)}..{dir (angle(Y-R)-90)}Y;
else:X{dir (angle(X-R)+90)}..{dir (angle(Y-R)+90)}Y;fi;
else:if angle(X)-angle(Y)>180:X{dir (angle(X-R)-90)}..{dir (angle(Y-R)-90)}Y;
else:X{dir (angle(X-R)+90)}..{dir (angle(Y-R)+90)}Y;fi;fi;
enddef;%------------------------------------------------------------
def drawPoiT(expr P,T,O,cr,cg,cb)=%------------------------------------
save Y;path q,r,s,pp;pair Y;
Y:=centPoi(P,T);q:=arcPoi(P,T,Y);
Y:=centPoi(T,O);r:=arcPoi(T,O,Y);
Y:=centPoi(O,P);s:=arcPoi(O,P,Y);
%Y:=centPoi(Q,P);p:=arcPoi(Q,P,Y);
pp:=q..r..s..cycle;
for i:=0 upto 3:fill pp rotated (90*i) scaled w withcolor (cr,cg,cb);endfor;
enddef;%------------------------------------------------------------
def drawPoiTT(expr P,T,O,cr,cg,cb)=%----------------------------------------------
save Y;path q,r,s,pp;pair Y;
Y:=centPoi(P,T);q:=arcPoi(P,T,Y);
Y:=centPoi(T,O);r:=arcPoi(T,O,Y);
Y:=centPoi(O,P);s:=arcPoi(O,P,Y);
%Y:=centPoi(Q,P);p:=arcPoi(Q,P,Y);
pp:=q..r..s..cycle;
fill pp scaled w withcolor (cr,cg,cb);
enddef;%------------------------------------------------------------
%
pair R,XX;path pop[],trip;
%
vardef nxtPoi(expr P,Q,R,S,O,n,nr,nl)=%--------------------------------
save T,U,V,X;pair T,U,V,X;
X:=centPoi(P,Q);T:=poiP(X,length(P-X),S);
U:=poiP(X,length(P-X),R);V:=poiP(X,length(P-X),O);
if length(T)<1:
if length(U)<1:
if length(P-U)>=length(P-T):
if length(Q-T)>=length(Q-U):
drawPoiT(P,T,V,0.3,0.5,0.7);drawPoiT(U,Q,V,0.1,0.3,0.5);
drawPoiT(T,U,V,0.9,0.7,0.5);drawPoiT(Q,P,V,0.7,0.5,0.3);
if n>1:
if min(length(T-P),length(T-P))>0.0001:if nr>0:
nxtPoi(P,T,U,Q,V,n-1,nr-1,nl);fi;fi;
if min(length(T-U),length(T-U))>0.0001:nxtPoi(T,U,Q,P,V,n-1,nr,nl);fi;
if min(length(Q-U),length(Q-U))>0.0001:if nl>0:
nxtPoi(U,Q,P,T,V,n-1,nr,nl-1);fi;fi;
fi;
fi;fi;fi;fi;
enddef;%------------------------------------------------------------
}%=======================================================================
\sendMP{%================================================================
pair O,A,B,C,D,E;O:=(0,0);
A:=(k,0) rotated 45;B:=A rotated 2ta;C:=B rotated 2ta;D:=C rotated 2ta;
drawPoiTT(A,B,O,0.3,0.5,0.7);drawPoiTT(C,D,O,0.1,0.3,0.5);
drawPoiTT(B,C,O,0.9,0.7,0.5);drawPoiTT(D,A,O,0.9,0.7,0.5);
%
nxtPoi(A,B,C,D,O,12,n-3,n-3);
}%=======================================================================
\end{MPpic}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\hfill~
%
%------------------------------------------------------------------------
\end{document}

enter image description here

share|improve this answer
3  
Welcome to TeX.SX. I replaced all the ¥ in your code with backslashes, I assume that was how it was supposed to be. You're also using some non-standard packages (i.e. packages that aren't on CTAN), such as qbgraph, mtcastle, so I for one cannot compile your code. –  Torbjørn T. Feb 13 at 11:51
2  
I'm sorry.\usepackage{mtcastle} \usepackage{ascmac} \usepackage{eclarith,qbgraph} are disused package.But \usepackage{MePoTeX} is requirement."MePoTeX" is a package explained in Japanese. homepage2.nifty.com/domae/metapost/mepotex.html . But metapost user should be able to read and use this code. –  user46110 Feb 17 at 8:08
up vote 108 down vote
+350

Plan B as per tohecz: I'm a security engineer at Facebook and this is my fault.

Properties of water and steam (IAPWS-SF95 formulation), enthalpy-entropy diagram, actually used by our students (and colleagues, from time to time).

Compiled with lualatex for memory reasons. I'll not post the code here, as it is quite a lot and wouldn't work on other computers anyway. That, of course, has a reason: The IAPWS-SF95 is not really easy to handle, so I wrote programs in C++ that output tables for the properties at a certain pressure, temperature, etc. This might have been possible with luatex, but I'm not really experienced in lua. I've added the tex code below.

The latex code reads in a table of iso lines that must be generated first, then calls the external binaries with appropriate command line arguments and reads back the resulting iso line tables. That takes about 45 minutes on a decent desktop PC, so I added an option not to regenerate all the data. Cosmetic runs now take only a few minutes.

Overview:

enter image description here

A close-up near the critical point:

enter image description here

You can see that some lines with constant steam quality (x) are cut off near the critical point, otherwise they would be to close to each other.

Some labels:

enter image description here

Extra labels or extended labels as you can see them above are also specified in the table that is read in first. Major and minor iso lines have different strength. The grid is quiet, gray. All glyphs have some white padding around them. I don't like the white spots appearing near the intersections of some lines, I haven't yet mastered that art (they are also present in the printed diagram, but not as prominent as on screen).

The layout is for A2 paper, I'm thinking about making an A0 version that starts at lower enthalpy/entropy. It would have a large empty area at the lower right that I'd fill with some table for looking up exact values.

Holding the real printed diagram in my hands with a real gray grid was really great. An older version of this diagram existed at our institute before, but we ran out of prints and it contained some wrong values. That was my motivation to create this one.

Thanks to tex sx - many of the tikz/pgfplots/pgfplotstable tricks I used in this diagram are actually yours!

EDIT: OK, as so many others have also posted their code I thought I'd just post mine as well, but without the C++ part.

mollier.tex (main file):

%\listfiles
\documentclass{article}
\usepackage[a2paper,landscape,margin=0.9cm]{geometry}

\usepackage[latin1]{luainputenc}
\usepackage[T1]{fontenc}

\usepackage{sfmath}
\usepackage{icomma} % german decimal separator in math mode

\usepackage[ngerman]{babel}
\usepackage[locale=DE]{siunitx}

\usepackage[outline]{contour}
\contourlength{0.5pt}
\usepackage{color}

\usepackage{tikz,pgfplots,pgfplotstable}
\usetikzlibrary{intersections,calc}
% \pgfplotsset{compat=1.5}

\usepackage{etoolbox}
% \usepackage{hyperref}


% plotted entropy range
\edef\smin{4000}
\edef\smax{9200}
\pgfmathsetmacro{\dsa}{500} % major tick size
\pgfmathsetmacro{\dsb}{100} % intermediate tick size
\pgfmathsetmacro{\dsc}{10} % minor tick size

% plotted enthalpy range
\edef\hmin{2000}
\edef\hmax{3900}
\pgfmathsetmacro{\dha}{500} % major tick size
\pgfmathsetmacro{\dhl}{100} % label ticks size
\pgfmathsetmacro{\dhb}{50} % intermediate tick size
\pgfmathsetmacro{\dhc}{5} % minor tick size

% min, critical, max pressure, critical temperature
\edef\pmin{700}
\edef\pCrit{22064000}
\edef\pmax{10000e5}
\edef\tCrit{373.946}

% default number of points per plotted line
\edef\nSamples{500}

\input{createTicks}

\tikzset{minor grid style/.style={ultra thin,color=black!50}}
\tikzset{intermediate grid style/.style={thin,color=black!50}}
\tikzset{major grid style/.style={thin,color=black!50}}
\tikzset{hidden plot/.style={draw=none}}

\pgfplotsset{minor p plot/.style={black,very thin}}
\pgfplotsset{major p plot/.style={black,semithick}}
\pgfplotsset{minor T plot/.style={smooth,magenta,very thin}}
\pgfplotsset{major T plot/.style={smooth,magenta,semithick}}
\pgfplotsset{minor x plot/.style={smooth,black,very thin}}
\pgfplotsset{major x plot/.style={smooth,black,semithick}}

\tikzset{p plot label/.style={inner sep=1pt,outer sep=0pt,above=1pt,anchor=base,sloped,font={\footnotesize}}}
\tikzset{t plot label/.style={inner sep=1pt,outer sep=0pt,above=1pt,anchor=base,sloped,font={\footnotesize}}}
\tikzset{x plot label/.style={inner sep=1pt,outer sep=0pt,above=1pt,anchor=base,sloped,font={\footnotesize}}}

\pgfplotstableset{input filter/.style={y expr=\thisrow{h}/1e3}}
\sisetup{detect-all=true,parse-numbers=false}
\pgfkeys{/pgf/number format/.cd,set thousands separator={},set decimal separator={,}}

\pgfplotsset{mollier axis/.style={
  xmin=\smin,xmax=\smax,width=52cm,
  ymin=\hmin,ymax=\hmax,height=38cm,
  scale only axis,
  major tick length={0pt},
  minor tick length={0pt},
  grid=none,
  xtick=\sLabelTicks,
  xticklabel={\pgfmathparse{\tick/1e3}\num{\pgfmathprintnumber{\pgfmathresult}}},
  ytick=\hLabelTicks,
  yticklabel={\pgfmathparse{\tick}\pgfmathprintnumber{\pgfmathresult}},
}}

\newbool{createPTables}
\newbool{createTTables}
\newbool{createXTables}
\setbool{createPTables}{false}
\setbool{createTTables}{false}
\setbool{createXTables}{false}

\begin{document}
  \thispagestyle{empty}
  \input{createTables}
  \noindent\centering
\begin{tikzpicture}
    \begin{axis}[mollier axis,
                axis x line*=top,
                axis y line*=right,
                ]
    \end{axis}
    \begin{axis}[mollier axis,
                xlabel={\textsf{spezifische Entropie $s$ in \si[per-mode=fraction]{\kilo\joule\per\kilogram\per\kelvin}}},
                ylabel={\textsf{spezifische Enthalpie $h$ in \si[per-mode=fraction]{\kilo\joule\per\kilogram}}},
                ]
      \input{drawGrid}
      % plots
      % plots are drawn using external data files created by createTables.tex
      % the data files don't need to be recreated in each run.
      \input{plotp}
      \input{plotT}
      \input{plotx}
      % labels
      % labels are placed by creating a path between 2 points on a plot (using intersections)
      % and then adding a node between these points.
      \input{placePLabels}
      \input{placeTLabels}
      \input{placeXLabels}
      % mark critical point
      % the critical point is at the end of the x=1 plot (or x=0)
      \filldraw (coord-x1000m-end) circle(2pt) node[
        p plot label,right=2pt,font={\sffamily\footnotesize}
      ] {\contour{white}{K.P.}};
      % title/info box
      \draw (rel axis cs:1,0) node[
        draw=black,fill=white,above left=1em,align=left,font={\sffamily\footnotesize}
      ] {
        \begin{minipage}{7.3cm}
          \includegraphics[width=\textwidth,keepaspectratio]{Logo_mit_TUHH_deu_weiss.pdf}\\[1\baselineskip]
          \Huge Mollier $h$,$s$-Diagramm\\[2pt]
          \LARGE für Wasser, nach IAPWS-95 [1]\\[0.5\baselineskip]
          \large Christoph Redecker\\
          Institut für Thermofluiddynamik\\
          TU Hamburg-Harburg
        \end{minipage}
      };
      % frame
      \draw[major grid style] (axis cs:\smin,\hmin) rectangle (axis cs: \smax,\hmax);
    \end{axis}
    % IAPWS reference
    \draw (current axis.below south east) node[outer sep=0pt,inner sep=0pt,left] {
      \footnotesize\sffamily
      \begin{minipage}{12.2cm}
        \begin{itemize}
          \item[{[1]}] IAPWS, \textit{Revised Release on the IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use} (2009).
          \texttt{http://www.iapws.org}.
        \end{itemize}
      \end{minipage}
    };
    \draw (current axis.below south west) node[outer sep=0pt,inner sep=0pt,right] {
      \footnotesize\sffamily v 1.2, 23.\,10.\,2012
    };
  \end{tikzpicture}
\end{document}

createTicks.tex:

\gdef\sMajorTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\smax - \smin)/\dsa)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\s}{\smin + (\n-1)*\dsa}%
    \xdef\sMajorTicks{\sMajorTicks\tickSep\s}
    \xdef\tickSep{, }
  }
}
\let\sLabelTicks\sMajorTicks

\gdef\sInterTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\smax - \smin)/\dsb)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\s}{\smin + (\n-1)*\dsb}%
    \xdef\sInterTicks{\sInterTicks\tickSep\s}
    \xdef\tickSep{, }
  }
}

\gdef\sMinorTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\smax - \smin)/\dsc)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\s}{\smin + (\n-1)*\dsc}%
    \xdef\sMinorTicks{\sMinorTicks\tickSep\s}
    \xdef\tickSep{, }
  }
}

\gdef\hMajorTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\hmax - \hmin)/\dha)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\h}{\hmin + (\n-1)*\dha}%
    \xdef\hMajorTicks{\hMajorTicks\tickSep\h}
    \xdef\tickSep{, }
  }
}

\gdef\hInterTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\hmax - \hmin)/\dhb)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\h}{\hmin + (\n-1)*\dhb}%
    \xdef\hInterTicks{\hInterTicks\tickSep\h}
    \xdef\tickSep{, }
  }
}

\gdef\hMinorTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\hmax - \hmin)/\dhc)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\h}{\hmin + (\n-1)*\dhc}%
    \xdef\hMinorTicks{\hMinorTicks\tickSep\h}
    \xdef\tickSep{, }
  }
}

\gdef\hLabelTicks{}
{
  \pgfmathsetmacro{\ticks}{floor((\hmax - \hmin)/\dhl)+1}
  \def\tickSep{}
  \foreach \n in {1,...,\ticks}%
  {
    \pgfmathsetmacro{\h}{\hmin + (\n-1)*\dhl}%
    \xdef\hLabelTicks{\hLabelTicks\tickSep\h}
    \xdef\tickSep{, }
  }
}

createTables.tex

\pgfplotstableset{create on use/pBar/.style={create col/expr={\thisrow{p}*1e-5}}}
\pgfplotstableset{create on use/pMPa/.style={create col/expr={\thisrow{p}*1e-6}}}
\pgfplotstableset{create on use/xVal/.style={create col/expr={\thisrow{x}*1e-3}}}
\pgfplotstableread[col sep=semicolon,
  columns/p/.style={string type},
  columns/style/.style={string type},
  columns/label/.style={string type},
  columns/cmdoptions/.style={string type}
]{pTable.tab}{\pTable}
\pgfplotstableread[col sep=semicolon,
  columns/t/.style={string type},
  columns/style/.style={string type},
  columns/label/.style={string type},
  columns/cmdoptions/.style={string type}
]{tTable.tab}{\tTable}
\pgfplotstableread[col sep=semicolon,
  columns/x/.style={string type},
  columns/style/.style={string type},
  columns/label/.style={string type},
  columns/cmdoptions/.style={string type}
]{xTable.tab}{\xTable}
%************************************************
\ifbool{createPTables}{%
  \pgfplotstablegetrowsof{\pTable}
  \foreach \i[evaluate=\i as \row using int(\i-1)] in {1,...,\pgfplotsretval}%
  {%
    \pgfplotstablegetelem{\row}{p}\of\pTable%
    \edef\p{\pgfplotsretval}%
    \pgfplotstablegetelem{\row}{cmdoptions}\of\pTable%
    \edef\cmdoptions{\pgfplotsretval}%
    \edef\shellcmd{../isobar/bin/Debug/isobar\space%
      --p=\p\space%
      --s=[\smin:\smax]\space%
      --h=[\hmin e3:\hmax e3]\space%
      % number of amples is set per plot in pTables.tab
      --snap\space%
      \cmdoptions\space%
      > ./data/p\p Pa.dat}%
    \immediate\write18{\shellcmd}%
  }%
}%
{} % end of \ifbool{createPTables}
%
%************************************************
\ifbool{createTTables}{%
  \pgfplotstablegetrowsof{\tTable}
  \foreach \i[evaluate=\i as \row using int(\i-1)] in {1,...,\pgfplotsretval}%
  {%
    \pgfplotstablegetelem{\row}{t}\of\tTable%
    \edef\t{\pgfplotsretval}%
    \pgfplotstablegetelem{\row}{cmdoptions}\of\tTable%
    \edef\cmdoptions{\pgfplotsretval}%
    \edef\shellcmd{../isotherm/bin/Debug/isotherm\space%
      --t=\t\space%
      --s=[\smin:\smax]\space%
      --h=[\hmin:\hmax]\space%
      --snap\space%
      \cmdoptions\space%
      > ./data/t\t C.dat}%
    \immediate\write18{\shellcmd}%
  }%
}%
{} % end of \ifbool{createTTables}
%
%************************************************
\ifbool{createXTables}{%
  \pgfplotstablegetrowsof{\xTable}
  \foreach \i[evaluate=\i as \row using int(\i-1)] in {1,...,\pgfplotsretval}%
  {%
    \pgfplotstablegetelem{\row}{x}\of\xTable%
    \edef\x{\pgfplotsretval}%
    \pgfplotstablegetelem{\row}{cmdoptions}\of\xTable%
    \edef\cmdoptions{\pgfplotsretval}%
    \edef\shellcmd{../isox/bin/Debug/isox\space%
      --x=\x e-3\space%
      --s=[\smin:\smax]\space%
      --h=[\hmin:\hmax]\space%
      --p=[\pmin:\pCrit]\space%
      --samples=100\space%\nSamples\space%
      \cmdoptions\space%
      > ./data/x\x e-3.dat}%
    \immediate\write18{\shellcmd}%
  }%
}%
{} % end of \ifbool{createTTables}

The file pTable.tab read in by the above file starts with this header and first entry:

p;style;label;cmdoptions
700;major p plot;normal;--samples=100 --t=[1:50]

This specifies that the 700 Pa plot is a major p plot, with a normal label. The binary for creating the isobar table is called with extra options to get 100 samples and limit the the temperature range to 1...50 °C (that helps solving the state equations).

drawGrid.tex:

% draw minor x grid lines
\foreach \s in \sMinorTicks
{
  \edef\temp{\noexpand\draw[minor grid style](axis cs:\s,\hmin) -- (axis cs:\s,\hmax);}
  \temp
}
% draw minor y grid lines
\foreach \h in \hMinorTicks
{
  \edef\temp{\noexpand\draw[minor grid style](axis cs:\smin,\h) -- (axis cs:\smax,\h);}
  \temp
}
% draw intermediate x grid lines
\foreach \s in \sInterTicks
{
  \edef\temp{\noexpand\draw[intermediate grid style](axis cs:\s,\hmin) -- (axis cs:\s,\hmax);}
  \temp
}
% draw intermediate y grid lines
\foreach \h in \hInterTicks
{
  \edef\temp{\noexpand\draw[intermediate grid style](axis cs:\smin,\h) -- (axis cs:\smax,\h);}
  \temp
}
% draw major x grid lines
\foreach \s in \sMajorTicks%
{
  \edef\temp{\noexpand\draw[major grid style](axis cs:\s,\hmin) -- (axis cs:\s,\hmax);}
  \temp
}
% draw major y grid lines
\foreach \h in \hMajorTicks
{
  \edef\temp{\noexpand\draw[major grid style](axis cs:\smin,\h) -- (axis cs:\smax,\h);}
  \temp
}

plotp.tex: (creates the pressure plots, other plot files are similar and omitted here)

\pgfplotstablegetrowsof{\pTable}
\foreach \i[evaluate=\i as \row using int(\i-1)] in {1,...,\pgfplotsretval}
{
  \pgfplotstablegetelem{\row}{p}\of\pTable
  \edef\p{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{style}\of\pTable
  \edef\style{\pgfplotsretval}
  \edef\temp{\noexpand\addplot[name path global=plot-p\p Pa,\style] table[x=s,input filter] {./data/p\p Pa.dat};} \temp
}

placePLabels.tex:

\pgfkeys{/pgf/number format/.cd,std,precision=8}
\path[name path global=pLabelPathA] (axis cs:9150,2500) .. controls (axis cs:8500,3775) .. (axis cs:7500,3730);
\path[name path global=pLabelPathB] (axis cs:9160,2500) .. controls (axis cs:8510,3785) .. (axis cs:7500,3740);
\foreach \i[evaluate=\i as \row using int(\i-1)] in {2,...,52}
{
  \pgfplotstablegetelem{\row}{p}\of\pTable
  \edef\p{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pBar}\of\pTable
  \edef\pBar{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pMPa}\of\pTable
  \edef\pMPa{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{label}\of\pTable
  \edef\Label{\pgfplotsretval}
  \expandafter\ifstrequal\expandafter{\Label}{short}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and pLabelPathA}},%
        name intersections={name=b,of={plot-p\p Pa and pLabelPathB}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\pgfmathprintnumber{\pBar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{normal}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and pLabelPathA}},%
        name intersections={name=b,of={plot-p\p Pa and pLabelPathB}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{long}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and pLabelPathA}},%
        name intersections={name=b,of={plot-p\p Pa and pLabelPathB}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$p = \noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}%
        = \noexpand\SI{\noexpand\pgfmathprintnumber{\pMPa}}{\mega\pascal}$}%
      };}%
    \temp%
  }{%
  }%
}
%below: #78 would be 10000 bar but that one gets an extra label
\pgfkeys{/pgf/number format/.cd,std,precision=2}
\foreach \i[evaluate=\i as \row using int(\i-1)] in {53,...,77}
{
  \pgfplotstablegetelem{\row}{p}\of\pTable
  \edef\p{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pBar}\of\pTable
  \edef\pBar{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pMPa}\of\pTable
  \edef\pMPa{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{label}\of\pTable
  \edef\Label{\pgfplotsretval}
  \expandafter\ifstrequal\expandafter{\Label}{short}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-t600C}},%
        name intersections={name=b,of={plot-p\p Pa and plot-t650C}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\pgfmathprintnumber{\pBar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{normal}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-t600C}},%
        name intersections={name=b,of={plot-p\p Pa and plot-t650C}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{long}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-t600C}},%
        name intersections={name=b,of={plot-p\p Pa and plot-t650C}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$p = \noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}%
        = \noexpand\SI{\noexpand\pgfmathprintnumber{\pMPa}}{\mega\pascal}$}%
      };}%
    \temp%
  }{%
  }%
}
% extra pCrit label:
\path[name intersections={name=a,of={plot-p22064e3Pa and plot-t600C}},%
  name intersections={name=b,of={plot-p22064e3Pa and plot-t650C}}]%
  (a-1) -- (b-1) node[midway,p plot label] {%
    \contour{white}{%
      $p = p_{crit} = \SI{\pgfmathprintnumber{220.64}}{\bar}$%
    }%
  };
% 10000 bar label:
\path (coord-t650C-start) -- (coord-t700C-start) node[midway,p plot label] {%
  \contour{white}{$\SI{\pgfmathprintnumber{10000}}{\bar}$}};
\pgfkeys{/pgf/number format/.cd,std,precision=8}
% in two-phase region:
\foreach \i[evaluate=\i as \row using int(\i-1)] in {1,...,65}
{
  \pgfplotstablegetelem{\row}{p}\of\pTable
  \edef\p{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pBar}\of\pTable
  \edef\pBar{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{pMPa}\of\pTable
  \edef\pMPa{\pgfplotsretval}
  \pgfplotstablegetelem{\row}{label}\of\pTable
  \edef\Label{\pgfplotsretval}
  \expandafter\ifstrequal\expandafter{\Label}{short}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-x800m}},%
        name intersections={name=b,of={plot-p\p Pa and plot-x850m}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\pgfmathprintnumber{\pBar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{normal}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-x800m}},%
        name intersections={name=b,of={plot-p\p Pa and plot-x850m}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$\noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}$}%
      };}%
    \temp%
  }{%
  }%
  \expandafter\ifstrequal\expandafter{\Label}{long}{%
    \edef\temp{%
      \noexpand\path[name intersections={name=a,of={plot-p\p Pa and plot-x800m}},%
        name intersections={name=b,of={plot-p\p Pa and plot-x850m}}]%
      (a-1) -- (b-1) node[midway,p plot label] {%
        \noexpand\contour{white}{$p = \noexpand\SI{\noexpand\pgfmathprintnumber{\pBar}}{\bar}%
        = \noexpand\SI{\noexpand\pgfmathprintnumber{\pMPa}}{\mega\pascal}$}%
      };}%
    \temp%
  }{%
  }%
}
share|improve this answer
3  
This is just "adult"graphy (saying politely) for an engineer; indeed, the +1 is deserved. –  Andrea L. Feb 9 at 8:12
2  
@AndreaL. Ooh, ’em curves. –  Konrad Rudolph Feb 9 at 15:11
3  
@Konrad do you want me to leave you two and a copy of the diagram alone for an hour or two? –  Christoph Feb 9 at 15:19
2  
The C++ part is what I am interested in. –  AlexG Feb 10 at 10:26
2  
This one should have won.. total geek-out! –  David Rutten Feb 14 at 15:45

Transformer

\documentclass{article}

\usepackage[
  hmargin = 2.4cm,
  vmargin = 3cm
]{geometry}
\usepackage[
  figureposition = bottom
]{caption}
\usepackage{pst-solides3d}

% Upright text as subscript in math mode.
\makeatletter
 \begingroup
  \catcode`\_=\active
  \protected\gdef_{\@ifnextchar|\subtextup\sb}
 \endgroup
\def\subtextup|#1|{\sb{\textup{#1}}}
\AtBeginDocument{\catcode`\_=12 \mathcode`\_=32768}
\makeatother

% Setup of caption.
\DeclareCaptionLabelSeparator{adjustment}{:\quad}
\captionsetup{
  font = small,
  labelfont = sc,
  labelsep = adjustment,
  width = 0.7\textwidth
}

%% Parameters
% Windings
\def\lWind{40}
\def\rWind{80}
% Radii
\def\rHelix{1.13}
\def\rWire{0.004}

% Constants
\def\factor{160} % \factor > \lWind,\rWind
\pstVerb{%
  /left 2 \lWind\space mul \factor\space div def
  /right 2 \rWind\space mul \factor\space div def
}

%% Colours
\colorlet{wireColor}{red!60}
\colorlet{coreColor}{cyan!50}
%% Wire
\newpsobject{wire}{psSolid}{%
  object = courbe,
  ngrid = 4365 left mul cvi 5,
  r = \rWire,
  fillcolor = wireColor,
  incolor = wireColor
}

\pagestyle{empty}

\begin{document}

\begin{figure}[htbp]
 \centering
  \begin{pspicture}(-6.6,-4.4)(6.6,4.2)
   \psset{%
     algebraic,
     solidmemory,
     viewpoint = 20 5 10 rtp2xyz,
     lightsrc = 20 60 60 rtp2xyz,
     Decran = 30,
     grid = false,
     action = none
   }
   %%--------- Core ----------
   \psSolid[
     object = anneau,
     h = 1.0,
     R = 4,
     r = 2.5,
     ngrid = 4,
     RotX = 90,
     RotY = 45,
     RotZ = 90,
     fillcolor = coreColor,
     name = core
   ]
   %%--------- Wire ----------
   % Left
   \defFunction{heliceA}(t){\rHelix*cos(\factor*t)}{\rHelix*sin(\factor*t)}{t/left}
   \wire[
     function = heliceA,
     range = 0 Pi left mul,
     name = wireA
   ](0,-2.25,-1.5)
   % Right
   \defFunction{heliceB}(t){\rHelix*cos(\factor*t)}{-\rHelix*sin(\factor*t)}{t/right}
   \wire[
     function = heliceB,
     range = 0 Pi right mul,
     name = wireB
   ](0,2.25,-1.5)
   %%------- Assembly --------
   \psSolid[
     object = fusion,
     base = core wireA wireB,
     action = draw**
   ]
   %%---- Connecting wire ----
   % Left
   \psline[
     linewidth = 1.5pt
   ](-6.8,2.71)(-3.705,2.71)(-3.705,2.31)
   \psline[
     linewidth = 1.5pt
   ](-6.8,-2.845)(-3.65,-2.845)(-3.65,-2.545)
   \pcline[
     linewidth = 0.5pt
   ]{<->}(-6,2.71)(-6,-2.845)
   \ncput*{\small $U_|p|$}
   \uput[315](-6,2.71){\small $+$}
   \uput[40](-6,-2.845){\small $-$}
   \psline{->}(-6.8,3.01)(-5.5,3.01)
   \uput[0](-5.5,3.01){\small $I_|p|$}
   \rput(-1.3,0){\small $N_|p|$}
   % Right
   \psline[
     linewidth = 1.5pt
   ](6.8,2.65)(3.48,2.65)(3.48,2.25)
   \psline[
     linewidth = 1.5pt
   ](6.8,-3.0)(3.41,-3)(3.41,-2.7)
   \pcline[
     linewidth = 0.5pt
   ]{<->}(6,2.65)(6,-3)
   \ncput*{\small $U_|s|$}
   \uput[225](6,2.65){\small $+$}
   \uput[140](6,-3){\small $-$}
   \psline{->}(5.5,2.95)(6.8,2.95)
   \uput[180](5.5,2.95){\small $I_|s|$}
   \rput(1.3,0){\small $N_|s|$}
  \end{pspicture}
 \caption{Transformer with $\lWind$~windings on the primary side and $\rWind$~windings on the secondary side.}
 \label{fig:transformer}
\end{figure}

\end{document}

output

share|improve this answer
4  
Reference source(s): exa050.tex, as part of the PSTricks 3D Gallery; Drawing 3D Transformer with TikZ or PSTricks –  Werner Feb 6 at 0:44
15  
I was expecting Optimus Prime, but i'm not disappointed –  Thomas Feb 6 at 6:41

Decimation

This diagram shows a decimation process in a database. The first level shows random samples, and subsequent levels calculate the min, mean, and max of groups of four entries from each previous level.

The cool thing about this is that all of the math, including the random number generation, is done directly in TikZ. Since the actual numbers didn't matter, I was able to choose a random seed that made the result look best.

\documentclass[tikz]{standalone}
\usepackage{fullpage}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{etoolbox}

\usetikzlibrary{decorations}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{calc}
\usetikzlibrary{arrows}

\newtoggle{quickdecim}
%\toggletrue{quickdecim} % Uncomment this to render more quickly (non-random)

\begin{document}

\begin{tikzpicture}[,
  ]
  \def\levels{4} % 2, 3, or 4
  \pgfmathtruncatemacro{\blocks}{4^(\levels-1)}
  \def\maxrand{99}
  \def\xoffset{1.1}
  \def\yoffset{2.6}
  \pgfmathsetseed{31337}
  \pgfmathsetmacro{\totalwidth}{10}
  \pgfmathsetmacro{\levelheight}{2.4}
  \pgfmathsetmacro{\sampleheight}{0.55}

  \definecolor{lowcolor} {rgb}{0.6,0.6,1}
  \definecolor{highcolor}{rgb}{0.6,1,0.6}

  \tikzstyle{Sample} = [
  draw, anchor=west,
  inner sep=0,
  outer sep=0,
  minimum height=\sampleheight * 1cm,
  font=\small,
  text=black,
  ]

  % make random numbers
  \pgfmathtruncatemacro{\runningrandarray}{random(\maxrand)}
  \foreach \x[count=\xi from 1] in {2,...,\blocks}{
    \let\temprand\runningrandarray
    \pgfmathtruncatemacro{\tempres}{random(\maxrand)}
    \xdef\runningrandarray{\temprand,\tempres}
  }
  \xdef\randarray{{\runningrandarray}}

  % boxes
  \foreach \level in {1,...,\levels} {
    \coordinate (level\level sample0) at
    (\xoffset - \totalwidth / 2,
    \yoffset + \levelheight - \levelheight * \level);
    \pgfmathsetmacro{\avgblocks}{4^(\level-1)}
    \pgfmathsetmacro{\levelblocks}{\blocks / \avgblocks}
    \pgfmathsetmacro{\samplewidth}{\totalwidth/\levelblocks}

    \foreach \i in {1,...,\levelblocks} {
      \iftoggle{quickdecim}{
        % can do this instead of using real samples, for speed
        \xdef\smin{5}
        \xdef\smean{50}
        \xdef\smax{95}
      }{
        % calculate sample values from the randarray
        \pgfmathsetmacro{\smin}{100}
        \pgfmathsetmacro{\smax}{0}
        \pgfmathsetmacro{\samplesum}{0}
        \pgfmathsetmacro{\countfrom}{(\i - 1) * \avgblocks}
        \pgfmathsetmacro{\countto}{\countfrom + \avgblocks - 1}
        \foreach \j in {\countfrom,...,\countto} {
          \pgfmathsetmacro{\tmp}{\samplesum + \randarray[\j] / \avgblocks}
          \xdef\samplesum{\tmp}
          \pgfmathtruncatemacro{\tmp}{min(\smin, \randarray[\j])}
          \xdef\smin{\tmp}
          \pgfmathtruncatemacro{\tmp}{max(\smax, \randarray[\j])}
          \xdef\smax{\tmp}
        };
        \pgfmathtruncatemacro{\tmp}{\samplesum}
        \xdef\smean{\tmp}
      }
      \pgfmathtruncatemacro{\cmin}{(\smin - 1) / (\maxrand - 1) * 100}
      \pgfmathtruncatemacro{\cmean}{(\smean - 1) / (\maxrand - 1) * 100}
      \pgfmathtruncatemacro{\cmax}{(\smax - 1) / (\maxrand - 1) * 100}
      \pgfmathtruncatemacro{\prev}{\i-1}

      \ifnumequal{\level}{1}{
        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -2cm,
        minimum width=\samplewidth cm,
        fill=highcolor!\cmean!lowcolor]
        (level\level samplemax\i) at (level\level sample0) {};
        \coordinate (level\level samplemin\i) at (level\level samplemax\i);
        \coordinate (level\level samplemean\i) at (level\level samplemax\i);
      }{
        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * 0cm,
        minimum width=\samplewidth cm,
        fill=highcolor!\cmin!lowcolor]
        (level\level samplemin\i) at (level\level sample0) {\smin};

        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -1cm,
        minimum width=\samplewidth cm,
        fill=highcolor!\cmean!lowcolor]
        (level\level samplemean\i) at (level\level sample0) {\smean};

        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -2cm,
        minimum width=\samplewidth cm,
        fill=highcolor!\cmax!lowcolor]
        (level\level samplemax\i) at (level\level sample0) {\smax};
      }
    };

    \coordinate (level\level sampleminlabel)
    at (level\level samplemin\levelblocks);
    \coordinate (level\level samplemeanlabel)
    at (level\level samplemean\levelblocks);
    \coordinate (level\level samplemaxlabel)
    at (level\level samplemax\levelblocks);
  };

  % arrows
  \foreach \next in {2,...,\levels} {
    \pgfmathtruncatemacro{\level}{\next-1}
    \pgfmathsetmacro{\amplitude}{3pt * \level + 1.5pt}
    \pgfmathsetmacro{\thislevelblocks}{\blocks / (4^(\level-1))}
    \pgfmathsetmacro{\nextlevelblocks}{\blocks / (4^(\level))}
    \foreach \block in {1,...,\nextlevelblocks} {
      \pgfmathtruncatemacro{\a}{4*(\block-1)+1}
      \pgfmathtruncatemacro{\b}{4*(\block-1)+4}
      \pgfmathtruncatemacro{\c}{4*(\block-1)+2}
      \draw [thick, decorate, decoration={brace, amplitude=\amplitude, mirror}]
      ([xshift=0.5pt]level\level samplemax\a.south west) --
      ([xshift=-0.5pt]level\level samplemax\b.south east);
      \draw[thick, -stealth]
      ([yshift=-\amplitude]level\level samplemax\c.south east) --
      (level\next samplemin\block .north);
    };
  };

  % text
  \foreach \level in {1,...,\levels} {
    \pgfmathtruncatemacro{\decim}{(4^(\level - 1))}
    % Level N
    \node[xshift=-2.5cm, yshift=6pt, anchor=west] (foo) at
    ($(level\level sample0 |- level\level samplemean1)$)
    {Level \level};
    % Samples
    \node[anchor=north, inner sep=0, font=\footnotesize] at (foo.south)
    {\ifnumequal{\level}{1}{(${\color{red}N}$ values)}
      {($3\cdot {\color{red}N / \decim}$ values)}};
  };

  \begin{scope}[anchor=west, inner sep=0, font=\footnotesize\itshape,
    text depth=0ex, text height=1.1ex, draw]
    \foreach \level in {2,...,\levels} {
      \node[xshift=3pt] at (level\level sampleminlabel) { min };
      \node[xshift=3pt] at (level\level samplemeanlabel) { mean };
      \node[xshift=3pt] at (level\level samplemaxlabel) { max };
    };
  \end{scope}

  \node[yshift=-0.8cm] at (foo.south) { $\vdots$ };

\end{tikzpicture}

\end{document}
share|improve this answer

If you throw a ball at a certain angle between 0 and 90 degrees relative to the horizontal line, the trajectory of the ball is a parabolic curve. The vertical component of its velocity is changing while the horizontal one remains unchanged.

The following code has not been optimized yet.

enter image description here

\documentclass[pstricks,border={12pt 32pt 26pt 12pt}]{standalone}
\usepackage{pstricks-add}
\makeatletter
\def\psLine{\pst@object{psLine}}% a special Line 
\def\psLine@i{\pst@getarrows{\begin@OpenObj \pst@getcoors[\psLine@ii}}
\def\psLine@ii{%
    \addto@pscode{
      \ifPst@noCurrentPoint\else\pst@cp\fi% current point?
      4 copy Pyth2 \psk@arrowlength ge 
        { \psline@iii \tx@Line }% arc and lineto type
        { pop pop pop pop } ifelse }%
  \end@OpenObj}
\makeatother

\usepackage[nomessages]{fp}
\newcommand\const[3][3]{%
    \expandafter\FPeval\csname#2\endcsname{round(#3:#1)}%
    \pstVerb{/#2 \csname#2\endcsname\space def}%
}
\newcommand\Const[3][3]{\begingroup\edef\temp{\endgroup\noexpand\const[#1]{#2}{#3}}\temp}

\Const{Tpeak}{1}
\Const{Theta}{80/180*pi}
\Const{Gravity}{10}
\Const{SpeedFactor}{0.2}
\Const{FPS}{25}

\def\X#1{Vinit*cos(Theta)*#1}
\def\Y#1{Vinit*sin(Theta)*#1-Gravity*pow(2,#1)/2}

\Const{Vinit}{Tpeak*Gravity/sin(Theta)}
\Const{Xpeak}{\X{Tpeak}}
\Const{Ypeak}{\Y{Tpeak}}

\def\point#1{%
    \pnode(!Vinit Theta RadToDeg 2 copy cos mul #1 mul 3 1 roll sin mul #1 mul Gravity #1 2 exp mul 2 div sub){P}
    \pscircle[linecolor=red,fillstyle=solid,fillcolor=yellow](P){3pt}
    \pnode[!Vinit Theta RadToDeg cos mul SpeedFactor mul 0](P){PX}
    \pnode[!0 Vinit Theta RadToDeg sin mul Gravity #1 mul sub SpeedFactor mul](P){PY}
    %
    \psLine[linecolor=blue]{->}(P)(PX)
    \psLine[linecolor=magenta]{->}(P)(PX|PY)
    \psLine[linecolor=blue]{->}(P)(PY)
    %
    \uput{1.5pt}[0](PX){\tiny$V_x$}
    \FPifgt{#1}{\Tpeak}
        \uput{1.5pt}[-90](PY){\tiny$V_y$}
    \fi
    \FPiflt{#1}{\Tpeak}
        \uput[90](PY){\tiny$V_y$}
    \fi
}


\Const{DeltaTime}{1/\FPS}
\Const[0]{TotalFrames}{\FPS*2*Tpeak}
\Const[0]{TotalFrames}{TotalFrames+1}

\begin{document}
\multido{\nt=0.000+\DeltaTime}{\TotalFrames}{%
\begin{pspicture}[showgrid=false](0,-35pt)(2\dimexpr\Xpeak\psxunit\relax,\dimexpr\Ypeak\psyunit+7pt\relax)
    \parabola[linewidth=0.5\pslinewidth,linestyle=dashed](0,0)(\Xpeak,\Ypeak)
    \point{\nt}
\end{pspicture}}
\end{document}
share|improve this answer
2  
Could you make the framerate higher so it looks like it is smoothly moving? –  Max Feb 10 at 15:25
1  
@Max: Yes. Done! Thanks for upvoting! –  Who is crazy first Feb 11 at 4:03

Configuration Space and Symbolic Subspace of a 2-Degrees of Freedom Robot

Depending on its configuration, it can either be in the symbolic state of penetrating the wall, or not penetrating it.

Configuration Space and Symbolic Subspace of a Simple Robot

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes}
\usepackage{amsmath}
\begin{document}

\newdimen\xbase
\newdimen\ybase 
\def\endDom{4}
\begin{tikzpicture}[domain=0:4]
  \def\ColSymBorder{black}
  \def\ColSymBorderTwo{black}
  \def\ColSymFill{gray!70}
  \def\ColSymFillTwo{gray!20}
  \def\wallColor{gray!70}
  \tikzstyle{block} = [draw, color=\ColSymBorder, ultra thick, fill=\ColSymFill, rectangle,  minimum height=3em, minimum width=6em];
  \draw[color=\ColSymBorderTwo, ultra thick, fill=\ColSymFillTwo] (0,0) rectangle (4,4);
  \draw (0,0) node[below,left]{$0^\circ$} -- (4,0) node[below,midway] {$\theta_1$} node[below,right] {$180^\circ$};
  \draw (0,0) -- (0,4) node[left,midway] {$\theta_2$} node[left] {$180^\circ$};

  \def\wallOffset{50pt}
  \def\marginOff{5pt}


  \draw[ultra thick,color=\ColSymBorder,fill=\ColSymFill, rounded corners=3pt] 
                   (0,0.2) .. controls (0,1) and (0,2) ..   (0,3.8)
                         .. controls (0.3,3.5) and (0.8,3.1) .. (1,2.6)
                         .. controls (1.4,2.0) and (1.6,1.2) .. (2,0)
                         .. controls (1,0) and (0.5,0) .. (0.3,0)
                         .. controls (0.2,0.1) and (0.1,0.2) .. (0,0.3);
                         %.. controls (3,0) and (2,0) .. (0,0);

  \newcounter{i}
  \setcounter{i}{0}
  \foreach \x in {1,100,...,180}{
   \foreach \y in {1,100,...,180}{
     %\ifthenelse{ {cos(\x)*40+50/cos(90-(\x+\y))} < 50}
     %\ifthenelse{ \lengthtest{ {\f{\x}} pt < 50 pt}}

       \pgfmathparse{ (
       (cos(\x)*40pt+sin(\x+\y)*50pt)<(\wallOffset+\marginOff)) &&
       (cos(\x)*40pt+sin(\x+\y)*50pt)>(\wallOffset-\marginOff))) ?1:0}
       \ifnum\pgfmathresult>0
          %penetrates the wall
          \stepcounter{i}
       \else
          %out of the wall
       \fi


   }
  }

  \draw[thick,color=\ColSymBorder] (-2,1) -- (0,1);
  \node[block] at (-3,1) {$s_0: $ penetratesWall};
  \draw[thick,color=\ColSymBorderTwo] (6,3) -- (4,3);
  \node[draw, color=\ColSymBorderTwo, ultra thick, fill=\ColSymFillTwo, rectangle,
  minimum height=3em, minimum width=6em] at (7,3) {$s_1: \neg$penetratesWall};

  %%%%%%%% PAINTING THE ROBOT STARTS HERE:

  \newcommand*{\Robot}[4]{
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \pgfmathsetlengthmacro{\rone}{40pt} %length link1
    \pgfmathsetlengthmacro{\rtwo}{50pt} %length link2
    \pgfmathsetlengthmacro{\rw}{10} %width of base rectangle
    \pgfmathsetlengthmacro{\thetaone}{#1} %angle base-link1
    \pgfmathsetlengthmacro{\thetatwo}{#2} %angle link1-link2
    \coordinate (base) at (#3,#4); %base coordinates

    %\coordinage (cspace) at ({#1/180*\endDom},{#2/180*\endDom})

    \path (base);
    \pgfgetlastxy{\xbase}{\ybase};
    \draw[thick,color=black] ({\xbase+1cm},{\ybase+3.0cm}) -- ({#1/180*\endDom},{#2/180*\endDom});
    \draw[fill=black] ({#1/180*\endDom},{#2/180*\endDom}) circle (2pt);


    \draw[thick,color=black] ({\xbase-1cm},{\ybase-0.5cm}) rectangle
    ({\xbase+3cm},{\ybase+3cm});

    \draw[fill=\wallColor] ({\xbase+\wallOffset}, {\ybase-0.5cm}) rectangle
    ({\xbase+3cm}, {\ybase+3cm});

    \pgfmathsetlengthmacro{\tx}{\rone*cos(\thetaone)+\xbase}
    \pgfmathsetlengthmacro{\ty}{\rone*sin(\thetaone)+\ybase}
    \coordinate (t1) at (\tx,\ty);

    \pgfmathsetlengthmacro{\sx}{\rtwo*sin(\thetaone+\thetatwo)+\tx}
    \pgfmathsetlengthmacro{\sy}{-\rtwo*cos(\thetaone+\thetatwo)+\ty}
    \coordinate (t2) at (\sx,\sy);
    \draw[ultra thick,black] (base) -- (t1);% node[below] {$\tx \ybase \xbase \ty$};
    \draw[ultra thick,black] (t1) -- (t2);% node[below] {$\tx \ybase \xbase \ty$};

    \draw[thick,color=black,fill=white!30] ({\xbase-0.5*\rw},{\ybase-0.5*\rw}) rectangle++ (\rw,\rw);
    \draw[thick,color=black,fill=white!10] (t1) circle (2pt);
    \draw[thick,color=black,fill=white!10] (t2) circle (2pt);


    %% dashed line to represent link two at 0 degree
    \pgfmathsetlengthmacro{\rtmp}{\rone }
    \pgfmathsetlengthmacro{\tmpx}{\rtmp*sin(\thetaone)+\tx}
    \pgfmathsetlengthmacro{\tmpy}{-\rtmp*cos(\thetaone)+\ty}
    \coordinate (tmp1) at (\tmpx,\tmpy);
    \draw[dashed,color=black] (t1) -- (tmp1);

    %% dashed line to represent link one at 0 degree
    \pgfmathsetlengthmacro{\tmpx}{\rone+\xbase}
    \pgfmathsetlengthmacro{\tmpy}{\ybase}
    \coordinate (tmp0) at (\tmpx,\tmpy);
    \draw[dashed,color=black] (base) -- (tmp0);


    \pgfmathsetlengthmacro{\tmpx}{\rone+\xbase}
    \pgfmathsetlengthmacro{\tmpy}{\ybase}

    \pgfmathsetlengthmacro{\tmpx}{0.9*\rone*cos(\thetaone)+\xbase}
    \pgfmathsetlengthmacro{\tmpy}{0.9*\rone*sin(\thetaone)+\ybase}
    \coordinate (tmp0t) at (\tmpx,\tmpy);

    \pgfmathsetlengthmacro{\tmpx}{0.9*\rtwo*sin(\thetaone+\thetatwo)+\tx}
    \pgfmathsetlengthmacro{\tmpy}{-0.9*\rtwo*cos(\thetaone+\thetatwo)+\ty}
    \coordinate (tmp1t) at (\tmpx,\tmpy);

    % ($(O)+(\StartAngle:-\Radius)$) is the center of the yellow circle

    \draw[bend right,thick,->]  (tmp1) to node [auto] {$\theta_2$} (tmp1t);
    \draw[bend right,thick,->]  (tmp0) to node [auto] {$\theta_1$} (tmp0t);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  }



  \Robot{40}{40}{-4}{-4.5}
  \Robot{70}{60}{1}{-4.5}
  \Robot{110}{25}{6}{-4.5}
\end{tikzpicture}


\end{document}
share|improve this answer

Mandelbrot Set

enter image description here

Well, I didn't really come up with this, especially the coloring function. I pieced the code together from different tutorials some time ago, and now simply translatet it to Asymptote.

real iterate(pair z, pair c, int N) {
    pair zsquare = 0;

    int n = 0;

    do {
        zsquare = (z.x * z.x, z.y * z.y);
        z = (zsquare.x + zsquare.y * -1, 2 * z.x * z.y) + c;
        ++n;
    }
    while (zsquare.x + zsquare.y < 4 && n < N);

    zsquare = (z.x * z.x, z.y * z.y);
    return n - log(.5 * log(zsquare.x + zsquare.y) / log(N)) / log(2);

    return n;
}

void mandelbrot(pair size, real zoom, pair pos, int N) {
    for(int x = 0; x < size.x; ++x) {
        for(int y = 0; y < size.y; ++y) {
            pair z = (x / size.x, y / size.y) * zoom - pos;

            real res = iterate(z, z, N) / N;

            fill(box((x, y), (x + 2, y + 2)), rgb(sin(res * 4), sin(res * 5), sin(res * 6)));
        }
    }
}

mandelbrot((300, 300), 3, (2, 1.5), 128);
share|improve this answer

Mexican Hat potential

Spontaneous Symmetry Breaking illustrated for a "mexican hat" potential.

Asymptote code:

import graph3;

size(200,200,IgnoreAspect);

currentprojection=perspective(5,2.7,3);

real f(pair z) {return -abs(z)^2+0.5*abs(z)^4;}

bbox3 b=limits(O,1.75(1,1,1));
currentlight=(1,-1,1);

picture surface=surface(f,(-1.3,-1.3),(1,1),nx=100,palegray);
add(surface);
draw(arc((0,0,-0.5),1,90,60,90,15),ArcArrow);
add(surface(f,(-0.5,-0.5),(0.5,0.5),nx=20,palegray));

yaxis(Label("$\phi^\dagger\phi$",1),b,red,Arrow);
zaxis(Label("$V(\phi^\dagger\phi)$",1),b,red,Arrow);
share|improve this answer
up vote 205 down vote
+300

The following image illustrates the blowup of a plane at a point--an important construction in algebraic geometry (compare the cover of this book). The image was produced using Asymptote. (Note: the code and the image have both been refined since they were first posted.)

The vector image may be viewed by following this link.

settings.outformat="pdf";
settings.render=0;
settings.prc=false;

usepackage("lmodern");
usepackage("fontenc","T1");
usepackage("amssymb");  // for the \mathbb command
defaultpen(fontsize(10pt));

import graph3;
size(400,400);
currentprojection=orthographic(5,-10,4);

real R=8;

struct scaler {
    private real factor;

    void operator init(real factor) {
        this.factor = factor;
    }

    real scale(real t) {return factor*atan(tan(t)/factor);}
    real invert(real t) {return tan(atan(t)*factor)/factor;}
}

scaler theScaler = scaler(6);

triple f(pair t) {
    real r = t.x;
    real theta = 2 * atan(t.y*2/pi);
//  real theta = -t.y;
    return (r*cos(theta),r*sin(theta),theScaler.scale(theta));
}

int resolution = 10;
real epsilon = .01;
real vmin = -pi/2;
real vmax = pi/2;
real umin = -R;
real umax = R;
splinetype[] Linear = new splinetype[] {linear, linear, linear};
splinetype[] ZMonotonic = new splinetype[] {notaknot, notaknot, monotonic};
surface sBack=surface(f,(umin,vmin),(0,vmax),nu=resolution, nv=2*resolution,  usplinetype=Linear, vsplinetype = ZMonotonic);
surface sFront = surface(f, (0,vmin), (umax,vmax), nu=resolution, nv=2*resolution, usplinetype=Linear, vsplinetype=ZMonotonic);

pen meshpen = heavygray + linewidth(0.2);

material surfacepen = 
    material(diffusepen=lightgray+opacity(0.5), 
        emissivepen=gray(0.3),
        specularpen=gray(0.2));

draw(sBack, surfacepen=surfacepen, meshpen=meshpen);
draw(f((0,vmin)) -- f((0,vmax)), darkgray+linewidth(1.0));   // the exceptional divisor
draw(sFront, surfacepen=surfacepen, meshpen=meshpen);


pen planePen = black+linewidth(0.3);

triple bottomPoint = f((0,vmin));
triple planeCenter = 2.0*bottomPoint;
draw((bottomPoint-.6Z)--(planeCenter+.6Z), arrow=Arrow3(TeXHead2), p=linewidth(0.9),
     L="$\pi_1$");

real planeZ = planeCenter.z;

triple h(pair t) {
    return (t.x, t.y, planeZ);
}

triple g(pair t) {
    triple projectFrom = f(t);
    return h((projectFrom.x, projectFrom.y));
}
triple g(real tx, real ty) { return g((tx, ty)); }

real planeRadius = R+1;
surface thePlane = surface(h, (-planeRadius,-planeRadius),(planeRadius,planeRadius),
    nu=1);

path3 planeOutline = h((-planeRadius,-planeRadius)) -- h((-planeRadius,planeRadius)) -- h((planeRadius,planeRadius)) -- h((planeRadius,-planeRadius)) -- cycle;

for (real u = 0; u <= R; u += R/resolution)
  draw(circle(planeCenter, u), planePen);
for (real v = vmin; v < vmax; v += (vmax-vmin)/(2*resolution)) {
  draw(g(umin,v) -- g(umax,v), planePen);
}
draw(planeOutline, p=planePen);

//Embed the label "\mathbb P^2" on the plane:
real labelScale = 1.5;  
Label planeLabel = Label(scale(labelScale, labelScale*1.3, 1)*"$\mathbb P^2$", fontsize(10pt));
Label placedPlaneLabel = shift((planeRadius-1.2),(planeRadius-1.5),planeCenter.z)*planeLabel;

label(planeLabel, position = (planeRadius-1.2, planeRadius-1.5, planeCenter.z));
share|improve this answer
19  
It would not be an exaggeration to say that I learned Asymptote in order to produce this image. –  Charles Staats Feb 5 at 18:37
4  
Info to Reproduce image: save code as blowup.asy and run at commandline/terminal asy blowup.asy –  texenthusiast Feb 6 at 14:59
2  
Nice. Would it make more sense to colour/style the lines so that the radial directions and the "circular" directions are distinguished upstairs? –  Willie Wong Feb 7 at 11:42

Power plant

Fossil-fuel power station (original code: http://pstricks.blogspot.com/2012/01/centrale-thermique-flammes-schematisee_07.html)

\documentclass[
  landscape
]{article}

\usepackage[utf8]{inputenc}
\usepackage[
  hmargin=2cm,
  vmargin=2.5cm
]{geometry}
\usepackage{
  pst-grad,
  pst-coil,
  pstricks-add
}

\psset{
  unit=1.5
}

%-------------------------------------------------------------------------------
%--------------------- Flammefarve: Kontinuerlig gradient ----------------------
%-------------------------------------------------------------------------------
\makeatletter
\pst@addfams{pst-HSB}
\define@key[psset]{pst-HSB}{HueBegin}{%
  \def\PstParametricplotHSB@HueBegin{#1}
}
\define@key[psset]{pst-HSB}{HueEnd}{%
  \def\PstParametricplotHSB@HueEnd{#1}
}
\define@boolkey[psset]{pst-HSB}[Pst@]{HSB}[true]{}
\psset[pst-HSB]{
  HueBegin=0,
  HueEnd=1,
  HSB=true
}
\psset{dimen=outer}

\def\parametricplotHSB{\pst@object{parametricplotHSB}}
\def\parametricplotHSB@i#1#2#3{{%
  \begin@ClosedObj
  \addto@pscode{%
    /t #1 def
    /dt #2 t sub \psk@plotpoints\space div def
    /t t dt sub def
    /Counter 0 def
    1 setlinejoin
    \psk@plotpoints {
      /t t dt add def
      /Counter Counter 1 add def
      #3
      \pst@number\psyunit mul exch
      \pst@number\psxunit mul exch
      1 Counter eq { moveto currentpoint /OldY ED /OldX ED }
        {\ifPst@HSB
          /PointY exch def
          /PointX exch def
          Counter \psk@plotpoints\space div
          \PstParametricplotHSB@HueEnd\space
          \PstParametricplotHSB@HueBegin\space sub mul
          \PstParametricplotHSB@HueBegin\space add
          1 1 sethsbcolor
          OldX OldY PointX PointY lineto lineto
          stroke
          PointX PointY moveto
      /OldX PointX def /OldY PointY def
        \else lineto \fi } ifelse
     } repeat }
   \end@ClosedObj}
  \ignorespaces}
\makeatother

\pagestyle{empty}

%-------------------------------------------------------------------------------

\begin{document}

\begin{center}
\newhsbcolor{ColorC}{.5 0.8 0}
\newhsbcolor{ColorD}{.5 0.5 0.5}
\begin{pspicture}(-3.9,-6.1)(11.8,3.5)
 {\psset{
    linewidth=3pt,
    linecolor=gray!40,
    linearc=0,
    bordercolor=black,
    border=1.1pt
  }
  \pspolygon[
    fillstyle=gradient,
    gradangle=10,
    gradbegin=orange!80,
    gradmidpoint=0,
    gradend=white
  ](-1.8,3.45)(-0.9,2)(-0.9,-1.6)(0.9,-1.6)(0.9,2.4)(-0.2,2.4)(-0.88,3.45)(-1.8,3.45)%          Brændkammeret med udfyldning
  \pspolygon(-1.8,3.45)(-0.9,2)(-0.9,-1.6)(0.9,-1.6)(0.9,2.4)(-0.2,2.4)(-0.88,3.45)(-1.8,3.45)% Brændkammerets omrids
  \pspolygon[
    linewidth=4pt
  ](-1.85,-2.65)(8.75,-2.65)(8.75,3.45)(-1.85,3.45)% Kraftværkets omrids
 }
  \pspolygon[
    linewidth=0.8pt,
    fillstyle=solid,
    fillcolor=black,
    opacity=1
  ](-1.35,-0.92)(-1.25,-0.85)(-1,-0.85)(-1,-0.95)(-0.85,-0.95)(-0.85,-1.15)(-1,-1.15)(-1,-1.45)(-1.25,-1.45)(-1.35,-1.38)% Brænder
%-------------------------------------------------------------------------------
%----------------------------------- Flamme ------------------------------------
%-------------------------------------------------------------------------------
 {\psset{
    linestyle=none,
    fillstyle=solid,
    fillcolor=yellow!50
  }
  \pscustom{%
    \pscurve(-0.87,-1)(-0.4,-0.75)(-0.55,-0.4)(-0.4,-0.13)
    \pscurve(-0.45,-0.33)(-0.2,-0.53)
    \psline(-0.2,-0.53)(-0.2,-0.97)
    \pscurve(-0.2,-0.97)(-0.6,-1.05)(-0.87,-1.01)
  }
  \pscustom{%
    \pscurve(-0.2,-0.53)(-0.17,-0.35)(0.1,-0.1)
    \pscurve(0.1,-0.1)(-0.01,-0.4)(0,-0.6)
    \pscurve(0,-0.6)(0.04,-0.52)(0.16,-0.46)
    \pscurve(0.16,-0.46)(0.1,-0.6)(0.17,-0.8)(0,-0.98)(-0.2,-0.97)
    \psline(-0.2,-0.97)(-0.2,-0.53)
  }
  \pscustom{%
    \pscurve(0.1,-0.7)(0.2,-0.6)(0.2,-0.36)(0.4,-0.1)
    \pscurve(0.4,-0.1)(0.31,-0.29)(0.33,-0.4)(0.39,-0.6)(0.3,-0.8)(0.1,-0.86)
    \psline(0.1,-0.86)(0.1,-0.7)
  }
 }
  \psframe[
    linecolor=black,
    linewidth=0.8pt,
    fillstyle=solid,
    fillcolor=black,
    opacity=1
  ](-1,-1.15)(-0.81,-0.95)
%-------------------------------------------------------------------------------
%--------------------------------- Kondensator ---------------------------------
%-------------------------------------------------------------------------------
  \pscustom[
    linestyle=none,
    fillstyle=gradient,
    gradangle=0,
    gradbegin=white,
    gradmidpoint=0,
    gradend=magenta!80
  ]{%
    \psarcn[liftpen=0](6.8,-0.2){2}{190}{165}
    \psline(!5.162 2 15 sin mul 0.2 sub)(5.162,0.92)(5.338,0.92)(!5.338 2 15 sin mul 0.2 sub)(!6.312 2 15 sin mul 0.2 sub)(6.312,0.92)(6.488,0.92)(!6.488 2 15 sin mul 0.2 sub)
    \psarcn[liftpen=0](4.8,-0.2){2}{15}{-10}
    \closepath%
  }
  \pscustom[
    linestyle=none,
    fillstyle=gradient,
    gradangle=0,
    gradbegin=blue!70,
    gradmidpoint=0,
    gradend=cyan!60
  ]{%
    \psarcn[liftpen=0](6.8,-0.2){2}{195}{190}
    \psarcn[liftpen=0](4.8,-0.2){2}{-10}{-15}
    \closepath%
  }
  \pscustom[
    linewidth=1.0pt
  ]{%
    \psarcn[liftpen=0](6.8,-0.2){2}{195}{165}
    \psline(!5.162 2 15 sin mul 0.2 sub)(5.162,0.92)(5.338,0.92)(!5.338 2 15 sin mul 0.2 sub)(!6.312 2 15 sin mul 0.2 sub)(6.312,0.92)(6.488,0.92)(!6.488 2 15 sin mul 0.2 sub)
    \psarcn[liftpen=0](4.8,-0.2){2}{15}{-15}
    \closepath%
  }
%-------------------------------------------------------------------------------
%------------------------- Vandledning i brændkammeret -------------------------
%-------------------------------------------------------------------------------
 \psset{
   coilheight=0.495,
   coilwidth=1.3,
   coilaspect=52
 }
  \rput{90}(0,0){%
    \psCoil[
      linewidth=0.07cm,
      linecolor=black,
      doubleline=true
    ]{250}{720}
  }
  \rput(0.15,0.395){%
    \parametricplotHSB[
      linewidth=1.4mm,
      plotpoints=500,
      HueBegin=0.6,
      HueEnd=0.84
    ]{270}{90}{0.88 t cos mul 0.36 t sin mul}
  }
 {\psset{
    linewidth=0.07cm,
    linecolor=black,
    doubleline=true
  }
  \rput{90}(0,0){\psCoil{600}{1200}}
  \rput{90}(0,0){\psCoil{850}{1400}}
  \rput{90}(0,0){\psCoil{1260}{1550}}
 }
 {\psset{
    linewidth=0.045cm,
    linecolor=magenta,
    doubleline=true
  }
  \rput{90}(0,0){\psCoil{470}{1200}}
  \rput{90}(0,0){\psCoil{850}{1400}}
  \rput{90}(0,0){\psCoil{1220}{1550}}
 }
%-------------------------------------------------------------------------------
 {\psset{
    linewidth=1.47mm,
    linecolor=magenta,
    linearc=0.15,
    bordercolor=black,
    border=1.1pt
  }
  \psline(0.2,1.943)(4.1,1.943)(4.1,1.6)
  \psline(4.65,1.6)(4.65,1.943)(5.75,1.943)(5.75,1.6)
 }
 {\psset{
    arrows=->,
    arrowinset=0,
    arrowscale=1.2,
    arrowlength=0.8,
    linewidth=0.6pt
  }
  \psline(5.25,0.5)(5.25,0.1)
  \psline(6.4,0.5)(6.4,0.1)
 }
  \pscircle[
    linewidth=0.8pt,
    fillstyle=solid,
    fillcolor=blue!20!green!70
  ](8.3,-0.4){0.17}
 {\psset{
    linewidth=1.3mm,
    linecolor=blue!20!green!70,
    linearc=0.15,
    bordercolor=black,
    border=1.1pt
  }
  \psline(8.18,-0.4)(5.1,-0.4)(5.1,-0.1)(9.4,-0.1)(9.4,-1.2)
  \psline(8.423,-0.4)(9.1,-0.4)(9.1,-1.2)
 }
%-------------------------------------------------------------------------------
%------------------------------------ Flod -------------------------------------
%-------------------------------------------------------------------------------
  \multido{\rA=1.05+0.1}{6}{%
    \psplot[
      linecolor=blue
    ]{8.9}{9.8}{x 1600 mul sin 0.02 mul \rA\space sub}
  }
%-------------------------------------------------------------------------------
%----------------------------------- Turbine -----------------------------------
%-------------------------------------------------------------------------------
  \psframe[
    linecolor=black,
    fillstyle=gradient,
    gradangle=0,
    gradbegin=blue!20!green!70,
    gradmidpoint=0,
    gradend=green!10
  ](3.9,0.9)(6.6,1.6)
  \psline(4.9,0.9)(4.9,1.6)
%-------------------------------------------------------------------------------
%----------------------------- Akse og turbinehjul -----------------------------
%-------------------------------------------------------------------------------
 {\psset{
    linecolor=black,
    linestyle=none,
    fillstyle=gradient,
    gradientHSB=true,
    gradangle=0,
    gradbegin=ColorC,
    gradmidpoint=0.5,
    gradend=ColorD
  }
  \psframe[
    gradmidpoint=0.4
  ](3.7,1.2)(8.47,1.3)
  \pspolygon(4,1.35)(4.8,1.5)(4.8,1.0)(4,1.15)
  \pspolygon(5.0,1.5)(5.7,1.35)(5.70,1.15)(5.0,1.0)
  \pspolygon(5.8,1.35)(6.5,1.5)(6.5,1.0)(5.8,1.15)
 }
 {\psset{
    fillstyle=vlines,
    hatchangle=0,
    hatchsep=2pt
  }
  \pspolygon(4,1.35)(4.8,1.5)(4.8,1.0)(4,1.15)
  \pspolygon(5.0,1.5)(5.7,1.35)(5.7,1.15)(5.0,1.0)
  \pspolygon(5.8,1.35)(6.5,1.5)(6.5,1.0)(5.8,1.15)
 }
 {\psset{
    linecolor=black,
    fillstyle=solid,
    fillcolor=blue!20!green!70,
    opacity=0.6,
    dimen=inner
  }
  \psframe(3.8,1.05)(3.9,1.45)
  \psframe(6.6,1.1)(6.7,1.4)
 }
%-------------------------------------------------------------------------------
%-------------------- Generator og magnetiseringsmekanisme ---------------------
%-------------------------------------------------------------------------------
 {\psset{
    linecolor=black,
    fillstyle=gradient,
    gradangle=0,
    gradbegin=blue!60!green!70,
    gradmidpoint=0,
    gradend=green!10
  }
  \psframe[
    dimen=inner
  ](6.95,1.1)(7,1.4)
  \psframe(7,0.9)(8,1.6)
  \psframe[
    gradbegin=yellow!90,
    gradend=yellow!20,
    dimen=inner
  ](8,1.05)(8.4,1.45)
 }
 {\psset{
    linecolor=black,
    linewidth=0.8pt
  }
  \psline(7.7,0.9)(7.7,0.8)(8.3,0.8)
  \psline(7.6,0.9)(7.6,0.7)(8.3,0.7)
  \psline(7.5,0.9)(7.5,0.6)(8.3,0.6)
 }
  \multido{\rB=0.6+0.1}{3}{%
    \rput(8.38,\rB){%
      \psplot[
        linecolor=black,
        linewidth=0.6pt
       ]{-0.01}{0.16}{x 2500 mul sin 0.02 mul}
    }
  }
%-------------------------------------------------------------------------------
  \pspolygon[
    fillstyle=solid,
    fillcolor=black
  ](8.2,-0.4)(8.36,-0.31)(8.36,-0.49)
  \psframe[
    fillstyle=vlines,
    hatchangle=90,
    hatchsep=1.5pt,
    hatchcolor=red,
    linewidth=0.8pt
  ](2.2,-0.8)(2.8,-0.2)
  \pscircle[
    linewidth=0.8pt,
    fillstyle=solid,
    fillcolor=blue!70
  ](3.2,-1.1){0.25}
  \pspolygon[
    fillstyle=solid,
    fillcolor=black
  ](3.05,-1.1)(3.3,-0.96)(3.3,-1.24)
 {\psset{
    linewidth=1.47mm,
    linecolor=blue!70,
    linearc=0.15,
    bordercolor=black,
    border=1.1pt
  }
  \psline(0.2,0.035)(2.5,0.035)(2.5,-1.1)(2.99,-1.1)
  \psline(3.4,-1.1)(5.8,-1.1)(!5.8 -2 15 sin mul 0.2 sub 0.0175 add)
 }
 \psset{
   arrows=->,
   arrowinset=0,
   arrowscale=1.2,
   arrowlength=0.8,
   linewidth=0.6pt
 }
  \psline(1.6,0.035)(1.2,0.035)
  \psline(0.2,0.82)(-0.2,0.85)
  \psline(1.2,1.943)(1.6,1.943)
  \psline(5.025,1.943)(5.425,1.943)
  \psline(7.5,-0.4)(7.1,-0.4)
  \psline(7.5,-0.1)(7.9,-0.1)
%-------------------------------------------------------------------------------
 {\scriptsize
 {\psset{
    linewidth=0.6pt
  }
  \rput(-0.85,2.7){\shortstack[l]{%
    \ Gas-\strut\\[-1.25ex]\quad
    kanal\strut}
  }
  \rput(-1.2,-2){Brænder}
  \psline(-1.2,-1.9)(-1.2,-1.2)
  \rput(0.25,-2){Brændkammer}
  \psline(0.25,-1.9)(0.25,-1.2)
  \rput(3.2,-1.5){Pumpe}
  \rput(3.5,-0.4){\shortstack[c]{%
    Forvarm-\strut\\[-1.25ex]
    ningsanlæg}
  }
  \psline(2.7,1.95)(2.7,2.55)
  \rput(2.7,2.7){Damp}
  \psline(1.77,0.035)(1.77,0.22)
  \rput(1.8,0.5){\shortstack{%
    Oversprøjt-\strut\\[-1.25ex]
    ningsvand\strut}
  }
  \rput(4.4,2.8){\shortstack[c]{%
    Overtryks-\strut\\[-1.25ex]
    turbine\strut}
  }
  \psline(4.4,1.5)(4.4,2.5)
  \rput(6.1,2.8){\shortstack{%
    Undertryks-\strut\\[-1.25ex]
    turbine\strut}
  }
  \psline(6.1,1.5)(6.1,2.5)
  \rput(7.5,3.2){Generator}
  \psline(7.5,1.5)(7.5,3.0)
  \rput(8.15,2.5){\shortstack{%
    Magneti-\strut\\[-1.25ex]
    serings-\strut\\[-1.25ex]
    maskine\strut}
  }
  \psline(8.15,1.4)(8.15,2.1)
  \rput(4.2,0.1){\shortstack{%
    Konden-\strut\\[-1.25ex]
    sator\strut}
  }
  \psline(4.5,0.1)(5.1,0.1)
  \rput(7.7,-0.8){Kølevand}
  \psline(7.7,-0.4)(7.7,-0.6)
  \rput(9.3,-1.8){Flod}
 }
 }
%-------------------------------------------------------------------------------
 \rput(-2,-4.5){%
  \psset{
    arrows=->,
    ArrowFill=true,
    arrowinset=0,
    arrowscale=0.7,
    arrowlength=0.5,
    framearc=0.05,
    linecolor=gray!40,
    dimen=outer
  }
  \psline[
    linewidth=0.7cm
  ](12,0)(14,0)
  \psline[
    linewidth=0.2cm,
    linearc=0.3
  ](12,-0.35)(12.5,-0.35)(12.5,-1.0)
  \psframe[
    linecolor=black
  ](10,-0.8)(12,0.8)
  \psline[
    linewidth=0.9cm
  ](8,0)(10,0)
  \psline[
    linewidth=0.2cm,
    linearc=0.3
  ](8,-0.45)(8.5,-0.45)(8.5,-1.1)
  \psframe[
    linecolor=black
  ](6,-0.8)(8,0.8)
  \psline[
    linewidth=1.1cm
  ](4,0)(6,0)
  \psline[
    linewidth=0.2cm,
    linearc=0.3
  ](4,-0.55)(4.5,-0.55)(4.5,-1.2)
  \psframe[
    linecolor=black
  ](2,-0.8)(4,0.8)
  \psline[
    linewidth=1.3cm
  ](0,0)(2,0)
  \psline[
    linewidth=0.2cm,
    linearc=0.3
  ](0,-0.65)(0.5,-0.65)(0.5,-1.3)
  \psframe[
    linecolor=black
  ](-2,-0.8)(0,0.8)
  \rput(-1,0){Brænder}
  \rput(3,0){Kedelrør}
  \rput(7,0){Turbine}
  \rput(11,0){Generator}
  \textcolor{red}{%
    \rput(0.55,0){\shortstack[l]{%
      \footnotesize Termisk\strut\\[-1.25ex]
      \footnotesize energi\strut}
    }
    \rput(4.6,0){\shortstack[l]{%
      \footnotesize Potentiel\strut\\[-1.25ex]
      \footnotesize energi\strut}
    }
    \rput(8.55,0){\shortstack[l]{%
      \footnotesize Kinetisk\strut\\[-1.25ex]
      \footnotesize energi\strut}
    }
    \rput(12.6,0){\shortstack[l]{%
      \footnotesize Elektrisk\strut\\[-1.25ex]
      \footnotesize energi\strut}
    }
    \rput(0.5,-1.5){\footnotesize Spildt energi}
    \rput(4.5,-1.4){\footnotesize Spildt energi}
    \rput(8.5,-1.3){\footnotesize Spildt energi}
    \rput(12.5,-1.2){\footnotesize Spildt energi}
  }
}
\end{pspicture}
\end{center}

fossil

Note that the text is converted into Danish.

Note: At pstricks.blogspot.com/2013/06/un-schema-de-centrale-electrique.html one can see a drawing of a nuclear power plant. I would've liked to add this code too, but I'm limited to 30k characters.

share|improve this answer

I couldn't bear to let this go without at least one example of a picture produced by mfpic. It is not very flashy, but it illustrates that mfpic has built-in commands to produce figures in the hyperbolic geometry of a disk (for those of us who study function theory in the unit disk.):

\documentclass{article}
\usepackage[metapost,mplabels]{mfpic}
\opengraphsfile{mypics}
\begin{document}
Hyperbolic metric disks:

\begin{mfpic}[72]{-1}{1}{-1}{1}
  \setmfpair{Z}{(dir 45)/3}
  \setmfpair{W}{Moebius (Z)(.5*dir -45)}
  \draw\gfill[gray(.94)]\circle{(0,0),1}
  \draw\gfill[gray(.87)]\pshcircle{Z,4/5}
  \gfill[gray(.80)]\pshcircle{Z,1/2}
  \draw\gfill[gray(.73)]\pshcircle{W,1/2}
  \draw\pshcircle{Z,1/2}
  \tlpointsep{3bp}
  \point{Z,W,(0,0)}
  \tlabel[br]{Z}{$z$}
  \tlabel[tl]{W}{$w$}
  \tlabel[tr]{(0,0)}{$0$}
\end{mfpic}

Hyperbolic geodesics:

\begin{mfpic}[72]{-1}{1}{-1}{1}
  \circle{(0,0),1}
  \draw\gfill[gray(.88)]
    \lclosed
    \connect
      \hypergeodesic{.999*dir 0, .999*dir 120}
      \hypergeodesic{.999*dir 120, .999*dir 240}
      \hypergeodesic{.999*dir 240, .999*dir 0}
    \endconnect
  \mfpfor{K=6,12,24,48}
    \mfpfor{J=0 upto K-1}
      \rotatepath{(0,0),J*(360/K)}\hypergeodesic{.999*dir 0, .999*dir (360/K)}
    \endmfpfor
  \endmfpfor
\end{mfpic}

\closegraphsfile
\end{document}

Some hyperbolic disks

Hyperbolic geodesics

share|improve this answer

Newton's rings.

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes}
\usepackage{amsmath}
\begin{document}
  \pagecolor{yellow!50}
  \begin{tikzpicture}[note/.style={rectangle callout, fill=#1}]
  \foreach \x in {1,2,...,22}{  
     \draw[thick] (0,0) circle ({sqrt(\x)});
  }
  \fill[black!100] (0,0) circle (1);
  \foreach \x in {23,24,...,28}{
    \draw[black!30] (0,0) circle ({sqrt(\x)});
  }
  \node (v1) at (-1.014,-6.5) {\Large $m^\text{th}$ ring};
  \draw[very thick,latex-](v1) -- (-1.014,-0.98);
  \node (v2) at (1.414,-5.8) {\Large $\left(m+1\right)^\text{th}$ ring};
  \draw[very thick,latex-](v2) -- (1.414,-1);
  \draw[very thick,-](1.414,6) -- (1.414,0);
  \draw[very thick,-](-1.414,6) -- (-1.414,0);
  \draw[very thick,latex-latex](-1.414,5.8) -- (1.414,5.8);
  \node at (0,6.1) {\Large $D_{m}$};
  \draw[very thick,latex-latex](4.6904,7.4) -- (-4.6904,7.4);
  \node at (0,7.7) {\Large $D_{m+21}$};
  \node [draw,note=white!100, callout relative pointer={(2.05,-2.8)}] at (-7,3) {\Large Take first
     reading};
  \node (v3) at (-4.6904,8) {\Large $m+21$};
  \draw[very thick,-](v3) -- (-4.6904,0);
  \node [draw,note=white!100, callout relative pointer={(-2.05,-2.8)}] at (7,3) {\Large Take last
      reading};
  \node (v4) at (4.6904,8) {\Large $m+21$};
  \draw[very thick,-](v4) -- (4.6904,0);
\end{tikzpicture} 
\end{document}

enter image description here

Explanation:

We have an experiment in optics to measure the focal length of a lens using Newton's ring set up. This diagram is an illustration provided in the manual depicting the rings pattern. The radii of the rings are accurately equal to square root of 1,2,3..... Students take readings for only 21 rings and hence they are made dark for visibility.

share|improve this answer

A picture from my first research project.

This is a graph obtained by studying how a certain monodromy action act on the coefficients of a polynomial potential (of degree 4) of a Schrödinger-type equation.

Each vertex is itself an infinite graph, but it is essentially a tree. The different superscripts determine the type of tree, and the substripts the lengths of the edges in the tree.

The edges represents monodromy actions.

ActionGRaph

\documentclass[a4paper,11pt,dvips]{paper}
\usepackage[all]{xy}
\xyoption{ps}
\xyoption{dvips}

\newcommand{\tta}{\Lambda^A}
\newcommand{\ttr}{\Lambda^R}
\newcommand{\ttl}{\Lambda^L}
\newcommand{\ttm}{\Lambda^M}
\newcommand{\ttc}{\Lambda^C}
\newcommand{\actA}{A}
\newcommand{\actB}{B}
\newcommand{\actE}{E}
\newcommand{\actR}{R}

\begin{document}
\pagestyle{empty}
%1 = ->
%3 = -->
%5 = ..>
\xymatrix @-1pc {
&\ttl_{2,3,2}\ar@/^/@{->}[dr]&&\ttl_{3,2,1}\ar@/^/@{->}[dr]&&\ttl_{4,1,0}\ar@/^/@{->}[dr]&&&&&&&&&&&&&&&&&\\
%
\ttl_{1,3,3}\ar@/^/@{->}[dr]&&\ttl_{2,2,2}\ar@/^/@{->}[dr]\ar@/^/@{..>}[ul]&&\ttl_{3,1,1}\ar@/^/@{->}[dr]\ar@/^/@{..>}[ul] &&\ttl_{4,0,0}\ar@{->}[dd]\ar@/^/@{..>}[ul] \ar@/^/@{-->}[rr] &&\ttc_{4,1,0} \ar@/^/@{..>}[ll]\ar@/^/@{-->}[rr]&& \ttc_{4,2,1}\ar@/^/@{..>}[ll]&&&&&&&&&&\\
%
&\ttl_{1,2,3}\ar@/^/@{->}[dr]\ar@/^/@{..>}[ul]&&\ttl_{2,1,2}\ar@/^/@{->}[dr]\ar@/^/@{..>}[ul] && \ttl_{3,0,1}\ar@{-->}[ur]\ar@{->}[dd]\ar@/^/@{..>}[ul] && &&&&&&&\\
%
\tta_{-2,4}\ar@/^/@{->}[rd]&&\ttl_{1,1,3}\ar@/^/@{->}[dr]\ar@/^/@{..>}[ul] && \ttl_{2,0,2}\ar@{-->}[ur]\ar@{->}[dd]\ar@/^/@{..>}[ul] && \ttm_{3,0,1}\ar@/^/@{-->}[rr]\ar@{..>}[ul]\ar@{->}[dd] &&\ttc_{3,1,1}\ar@/^/@{..>}[ll]\ar@/^/@{-->}[rr]&& \ttc_{3,2,1}\ar@/^/@{..>}[ll]&&&\\
%
& \tta_{-1,4}\ar@/^/@{->}[rd]\ar@/^/@{..>}[ul] && \ttl_{1,0,3}\ar@{-->}[ur]\ar@{->}[dd] \ar@/^/@{..>}[ul] && \ttm_{2,1,1}\ar@{-->}[ur]\ar@{..>}[ul]\ar@{->}[dd] &&&&&&&\\
%Center Below
&&\tta_{0,4}\ar@/^/@{..>}[ul] \ar@{-->}[ur]\ar@/^/@{->}[dl] && \ttm_{1,2,1}\ar@{..>}[ul]\ar@{-->}[ur]\ar@{->}[dd] && \ttm_{2,0,2}\ar@/^/@{-->}[rr]\ar@{..>}[ul]\ar@{->}[dd] &&\ttc_{2,1,2}\ar@/^/@{..>}[ll]\ar@/^/@{-->}[rr]&&\ttc_{2,2,2}\ar@/^/@{..>}[ll]&&&\\
%
&\tta_{1,4}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl]&&\ttr_{1,0,3}\ar@{..>}[ul]\ar@{-->}[ur] \ar@/^/@{->}[dl]&& \ttm_{1,1,2}\ar@{-->}[ur]\ar@{..>}[ul]\ar@{->}[dd] &&&&&&&&\\
%
\tta_{2,4}\ar@/^/@{-->}[ur]&&\ttr_{1,1,3}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl]&& \ttr_{2,0,2}\ar@{..>}[ul]\ar@{-->}[ur]\ar@/^/@{->}[dl]&&  \ttm_{1,0,3}\ar@/^/@{-->}[rr]\ar@{..>}[ul]\ar@{->}[dd] &&\ttc_{1,1,3}\ar@/^/@{..>}[ll]\ar@/^/@{-->}[rr] &&\ttc_{1,2,3}\ar@/^/@{..>}[ll]&&&&&&&&\\
%
&\ttr_{1,2,3}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl] &&\ttr_{2,1,2}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl]&& \ttr_{3,0,1}\ar@{..>}[ul]\ar@{-->}[ur]\ar@/^/@{->}[dl]&&  &&&&&&&&&&&&\\
%
\ttr_{1,3,3}\ar@/^/@{-->}[ur]&&\ttr_{2,2,2}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl] &&\ttr_{3,1,1}\ar@/^/@{-->}[ur]\ar@/^/@{->}[dl]&&\ttr_{4,0,0}\ar@{..>}[ul] \ar@/^/@{->}[dl] \ar@/^/@{-->}[rr] &&\ttc_{0,1,4}\ar@/^/@{..>}[ll]\ar@/^/@{-->}[rr]&& \ttc_{0,2,4}\ar@/^/@{..>}[ll]&&&&&&&&&&\\
%
&\ttr_{2,3,2}\ar@/^/@{-->}[ur]&&\ttr_{3,2,1}\ar@/^/@{-->}[ur]&&\ttr_{4,2,0}\ar@/^/@{-->}[ur]&& \\
\actA_1^2: \ar@{->}[r]&&\actA_3^2:\ar@{-->}[r]&&\actA_5^2: \ar@{..>}[r]&&&&&&&&&&&&&&
}
\end{document}
share|improve this answer

Here is a picture intended to explain the disk method for computing the volume of a solid of revolution. I originally created it for my calculus class; I later redrew it to use as the central example in my still-unfinished Asymptote tutorial. Consequently, the code is fairly mature.

It is, of course, drawn using Asymptote.

The source code:

//Function to return a brace path
real innerangle = radians(60);
real outerangle = radians(70);
real midangle = radians(0);
path brace(pair a, pair b, real amplitude = .14*length(b-a)) {
  transform t = identity();
  real length = length(b-a);
  real sign = 1;
  if (amplitude < 0) {
    //    amplitude *= -1;
    sign = -1;
  }
  path brace = (0,0){expi(sign*outerangle)} :: {expi(sign*midangle)}(length/4, amplitude/2)
          :: {expi(sign*innerangle)} (length/2, amplitude) {expi(-sign*innerangle)}
  :: {expi(-sign*midangle)}(3*length/4, amplitude/2) :: {expi(-sign*outerangle)} (length,0);
  real angle = degrees(atan2((b-a).y, (b-a).x));
  t = rotate(angle)*t;
  t = shift(a) * t;
  return t * brace;
}

//Define the command drawshifted, to be used later
void drawshifted(path g, pair trueshift, picture pic = currentpicture, Label label="", pen pen=currentpen, arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin, marker marker=nomarker)
{
  picture opic;
  draw(opic, L=label, g, p=pen, arrow=arrow, bar=bar, margin=margin, marker=marker);

  pic.add(new void(frame f, transform t) {
      add(f,opic.fit(shift(trueshift)*t));
    });
  pic.addBox(min(opic), max(opic), trueshift, trueshift);
}

usepackage("amsmath");

real yellowPart = 0.2;
real unit = 2cm;
real truecm = cm / unit;
unitsize(unit);
pen backgroundpen = yellowPart*yellow + (1-yellowPart)*white;
frame finish() {
  currentlight.background = backgroundpen;
  frame toreturn = bbox(backgroundpen, Fill);
  currentpicture = new picture;
  unitsize(unit);
  return toreturn;
}

/*------------------------------*/

//Basic settings
settings.outformat="pdf";
defaultpen(fontsize(10pt));
import graph;

//Save some important numbers.
real xmin = -0.1;
real xmax = 2;
real ymin = -0.1;
real ymax = 2;

//Draw the graph and fill the area under it.
real f(real x) { return sqrt(x); }
path s = graph(f, 0, 2, operator..);
path fillregion = s -- (xmax,0) -- cycle;
pen fillpen = mediumgray;
fill(fillregion, fillpen);
draw(s, L=Label("$y=f(x)$", position=EndPoint));

//Fill the strip of width dx
real x = 1.4;
real dx = .05;
real t0 = times(s,x)[0];
real t1 = times(s,x+dx)[0];
path striptop = subpath(s,t0,t1);
filldraw((x,0) -- striptop -- (x+dx,0) --  cycle, black);

//Draw the bars labeling the width dx
real barheight = f(x+dx);
pair barshifty = (0, 0.2cm);
Label dxlabel = Label("$dx$", position=MidPoint, align=2N);
drawshifted((x,barheight) -- (x+dx, barheight), trueshift=barshifty, label=dxlabel, bar=Bars);

//Draw the arrows pointing inward toward the dx label
real myarrowlength = 0.3cm;
margin arrowmargin = DotMargin;
path leftarrow = shift(barshifty) * ((-myarrowlength, 0) -- (0,0));
path rightarrow = shift(barshifty) * ((myarrowlength, 0) -- (0,0));
draw((x, barheight), leftarrow, arrow=Arrow(), margin=arrowmargin);
draw((x+dx, barheight), rightarrow, arrow=Arrow(), margin=arrowmargin);

//Draw the bar labeling the height f(x)
real barx = x + dx;
pair barshiftx = (0.42cm, 0);
Label fxlabel = Label("$f(x)$", align=(0,0), position=MidPoint, filltype=Fill(fillpen));
drawshifted((barx,0) -- (barx, f(x)), trueshift=barshiftx, label=fxlabel, arrow=Arrows(), bar=Bars); 

//Draw the axes on top of everything that has gone before
arrowbar axisarrow = Arrow(TeXHead);
Label xlabel = Label("$x$", position=EndPoint);
draw((xmin,0) -- (xmax,0), arrow=axisarrow, L=xlabel);
Label ylabel = Label("$y$", position=EndPoint);
draw((0,ymin) -- (0,ymax), arrow = axisarrow, L=ylabel);

//Draw the tick mark on the x-axis
path tick = (0,0) -- (0,-0.15cm);
Label ticklabel = Label("$x$", position=EndPoint);
draw((x,0), tick, L=ticklabel);

frame pic2dFrame = finish();

/* ----------------------------------------------------- */

settings.prc = false;
settings.render=8;
import three;

currentprojection = orthographic(5,0,10, up=Y);
//currentprojection=oblique;
//currentprojection=perspective(6,0,10,up=Y);

pen color = white;
material surfacepen = material(diffusepen=color+opacity(1.0), emissivepen=0.2*color);
material planepen = material(diffusepen=opacity(0.6), emissivepen=0.8*color);
pen diskpen = black+opacity(1.0);

path3 p3 = path3(s);
draw(p3);

surface FilledRegion = surface(fillregion);
draw(FilledRegion, surfacepen = gray(0.6) + opacity(0.8));

surface solidsurface = surface(p3, c=O, axis=X);
draw(solidsurface, surfacepen=surfacepen);

/*
int n = length(p3);
for (real i = 0; i <= n; i += n/10) {
  if (i >= n) i -= .01;
  draw(solidsurface.vequals(i), gray(0.3));
}
*/
draw(solidsurface.vequals(length(p3) - .001), gray(0.3));

real extra = 0.4 truecm;
path planeboundary = (xmin,ymin) -- (xmax+extra,ymin) -- (xmax+extra,ymax+extra) -- (xmin,ymax+extra) -- cycle;
path planeoutside = planeboundary -- fillregion -- cycle;
draw(surface(planeoutside), surfacepen=planepen);

transform pushoutside = shift(0,.001);
striptop = pushoutside*striptop;
path3 dVtop = path3(striptop);
path3 openStrip = (x,0,0) -- dVtop -- (x+dx,0,0);
surface disk = surface(openStrip, c=O, axis=X);
draw(disk, diskpen);

triple cameraDirection(triple pt, projection P = currentprojection) {
  if (P.infinity) {
    return unit(P.camera);
  } else {
    return unit(P.camera - pt);
  }
}

triple towardCamera(triple pt, real dist = 1 truecm, projection P = currentprojection) {
  return pt + dist*cameraDirection(pt, P);
}

draw(xmin*X -- xmax*X, arrow=Arrow3(TeXHead2(normal=Z)));
draw(ymin*Y -- ymax*Y, arrow=Arrow3(TeXHead2(normal=Z)));
label("$x$", position=towardCamera(xmax*X), align = E);
label("$y$", position=towardCamera(ymax*Y), align=N);

frame pic3dFrame = finish();

/* ----------------------------------------------------------------- */

currentprojection=orthographic((3,0,10), up=Y);

diskpen = mediumgray;
draw(disk, diskpen);

transform3 T = rotate(10, X);
path3 brace = T*path3(brace((x+dx,barheight), (x+dx,0)));
draw(brace--cycle);
label("$r=f(x)$", position=midpoint(brace), align=E);

//Draw the bars labeling the width dx
path3 dxlabelpath = T * ((x, barheight, 0) -- (x+dx, barheight, 0));
draw(dxlabelpath, L=dxlabel, Bars3);

arrow(relpoint(dxlabelpath,0), dir=W, length=myarrowlength, margin=DotMargin3, arrow=Arrow3(emissive(black)));
arrow(relpoint(dxlabelpath,1), dir=E, length=myarrowlength, margin=DotMargin3, arrow=Arrow3(emissive(black)));

draw(xmin*X -- xmax*X, arrow=Arrow3(TeXHead2(normal=Z)));
draw(ymin*Y -- ymax*Y, arrow=Arrow3(TeXHead2(normal=Z)));
label("$x$", position=towardCamera(xmax*X), align = E);
label("$y$", position=towardCamera(ymax*Y), align=N);

frame oneSlice = finish();
/* ----------------------------------------------------------------- */

label(minipage("\raggedright Dimensions of infinitesimally thin sheet: 
\begin{description}
\item[Area:] $\pi r^2 = \pi [f(x)]^2$
\item[Thickness:] $dx$
\item[Volume:] $dV = \text{Area}\cdot\text{thickness} = \pi [f(x)]^2\;dx$
\end{description}"
,6cm));

frame labelFrame = finish();

/* ----------------------------------------------------------------- */

unit = 1;
unitsize(unit);
add(pic3dFrame);
add(labelFrame, position=(max(pic3dFrame).x, min(pic3dFrame).y - 1cm), align=SW);
pic3dFrame = finish();

/* ----------------------------------------------------------------- */

//unitsize(1);    // Set the usual (postscript) coordinates.
add(pic2dFrame);
add(pic3dFrame, position=max(pic2dFrame), align=SE);
add(oneSlice, position=min(pic2dFrame)+(0,-1cm), align=SE);

// Scale up by 4 in order to increase resolution.
shipout(scale(4)*finish());
share|improve this answer
2  
Very nice tutorial. I hope you'll find the time to finish it. –  Philipp Feb 11 at 20:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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