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.

I would like to draw generic amoeba-like shapes with TikZ and don't really want to think too deeply about its boundary. Basically a closed connected set with smooth locally convex boundaries.

Any ideas how to do this easily?

share|improve this question
1  
Perhaps this can help you get started: Curve through a sequence of points with Metapost and TikZ. It just a matter of picking the points to get the desired shape. Try adapting it and if you run into difficulties post an update here. –  Peter Grill May 8 '12 at 21:46
    
Thanks Peter. It might take me a while, but I will try it and report back. –  fg nu May 9 '12 at 7:53

3 Answers 3

up vote 16 down vote accepted

Here's an example using one of the examples from the question that Peter Grill links to. You need the code from the TeX-SX Launchpad site: download the file hobby.dtx and run tex hobby.dtx to generate the files. Run pdflatex hobby.dtx to produce the documentation. Once you've done that, the code is simple:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{hobby}

\begin{document}
\begin{tikzpicture}
\fill[green!50] (0,0) .. (1,0) .. (1,3) .. (0,3) .. (0,1.5) .. cycle;
\fill[green!50] (3,0) .. +(1,0) .. +(1,2) .. +(1,3) .. +(0,3) .. cycle;
\fill[green!50] (6,0) .. +(1,0) .. +(1,1) .. +(1,2) .. +(1,3) .. +(0,3) .. +(0,1.5) .. cycle;
\end{tikzpicture}
\end{document}

produces:

amoeba shapes

(although you should be aware that the specific syntax I've used above might break in future versions of TikZ; there's an alternative notation that definitely won't)

share|improve this answer
    
Much appreciated Andrew. :) –  fg nu May 30 '12 at 19:35
    
Note that the .. cycle syntax no longer works with hobby. See tex.stackexchange.com/a/121310/86 for details and how to fix it. –  Loop Space Jul 9 '13 at 8:01

More realistic amoeba with PSTricks.

First Version

Please skip this first version (as there is a small glitch) and jump to the final version.

In this version I use \psparametricplot. After meticulously figuring out its behavior, I noticed that the last node is always included to create the closed curve. As a result, the first node and the last node are on the same radial line that make the curve has a visual defect on the curved line joining them.

I have no idea how to exclude the last node when using \psparametricplot.

enter image description here

\documentclass[pstricks]{standalone}
\usepackage{pst-plot}
\psset
{
    plotstyle=ccurve,
    fillstyle=solid,
    fillcolor=gray,
}
\begin{document}
\begin{pspicture}(-3,-3)(3,3)
\psparametricplot[plotpoints=40]{0}{360}{/R rand 1001 mod 1000 div 1.5 add def R t PtoC}
\end{pspicture}
\end{document}

Animation

enter image description here

\documentclass[pstricks]{standalone}
\usepackage{pst-plot}
\psset
{
    plotstyle=ccurve,
    fillstyle=solid,
    fillcolor=gray,
}

\begin{document}
\multido{\i=4+4}{20}{%
\begin{pspicture}(-3,-3)(3,3)
\psparametricplot[plotpoints=\i]{0}{360}{/R rand 1001 mod 1000 div 1.5 add def R t PtoC}
\end{pspicture}}
\end{document}

Final version

In this version I use \curvepnodes to produce a list of nodes. \Pnodecount represents the index of the last element.

Therefore,

\multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}

exludes the last node.

One advantage of using \curvepnodes is that we don't need to calculate the angle step.

enter image description here

\documentclass[pstricks]{standalone}

\usepackage{pst-node,pst-plot}
\psset{fillstyle=solid,fillcolor=gray}

\def\points{}
\pstVerb{666 srand}
\def\N{25}

\begin{document}
\begin{pspicture}(-3,-3)(3,3)
\curvepnodes[plotpoints=\N]{0}{360}{rand 16 mod 15 div 1.5 add t PtoC}{P}
\multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}
\expandafter\psccurve\points
\end{pspicture}
\end{document}

Animation

enter image description here

\documentclass[pstricks]{standalone}

\usepackage{pst-node,pst-plot}
\usepackage{graphicx}

\newsavebox\IBox
\savebox\IBox{\includegraphics[width=6cm]{example-grid-100x100pt}}
\psset
{
    fillstyle=solid,
    fillcolor=gray,
    xunit=\dimexpr\wd\IBox/6,
    yunit=\dimexpr\ht\IBox/6,
}

\pstVerb{666 srand}

\begin{document}
\multido{\io=15+5}{10}{%
\def\points{}%
\begin{pspicture}(-3,-3)(3,3)
\curvepnodes[plotpoints=\io]{0}{360}{rand 16 mod 15 div 1.5 add t PtoC}{P}
\multido{\ii=0+1}{\Pnodecount}{\xdef\points{\points (P\ii)}}
\begin{psclip}{\expandafter\psccurve\points}
    \rput(0,0){\usebox\IBox}
\end{psclip}
\end{pspicture}}
\end{document}
share|improve this answer

I [...] don't really want to think too deeply about its boundary. Basically a closed connected set with smooth locally convex boundaries.

Whenever I have to draw curves when I don't want to think too deeply about its boundary, I just use randomized curves. For example, here is a solution using Metapost + Metafun (I am posting ConTeXt code, but it should work in standalone metapost as well)

EDIT As Karl's student's answer illustrates, you get more realistic looking amoeba shapes if you start randomizing with more points. Based on that idea, here is another solution: (I think that the amoeba with 20 points looks rather realistic).

enter image description here

\startMPdefinitions
  vardef amoeba (expr n) =
      (for i = 0 step 360/n until 360 - 360/n : (0.5*tand(i mod (30) + 20) randomized 0.1)*dir(i randomized 5) .. endfor cycle)
  enddef;
\stopMPdefinitions


\starttext

\startMPpage[offset=2mm]
  path a ; 

  for i = 1 upto 5 :
      a := amoeba(10*i) scaled 2cm shifted (i*3cm,0);

      fill a withcolor 0.8white;
      draw a withpen pencircle scaled 2bp;
  endfor

\stopMPpage


\stoptext

Breakdown of code:

  • n: Number of points.
  • (0.5*tand(i mod (30) + 20) randomized 0.1): vary the distance of the point from the origin according to the angle i.
  • dir(i radnomized 5): i denotes the angle. Randomize the angle by 5 degrees.

Previous answer

enter image description here

or with less randomness

enter image description here

These curves were obtained using

\startMPdefinitions
  vardef amoeba =
      (fullcircle randomized 0.8 cornered 0.15 randomized 0.1) 
  enddef;
\stopMPdefinitions

\starttext

\startMPpage[offset=2mm]
  path a ; 

  for i = 1 upto 5 :
      a := amoeba scaled 2cm shifted (i*3cm,0);

      fill a withcolor 0.8white;
      draw a withpen pencircle scaled 2bp;
  endfor

\stopMPpage

\stoptext

In the second diagram, I changed randomized 0.8 to randomized 0.3. Breakdown of the code:

  • fullcircle: draws a circle of diameter 1 centered around origin
  • randomized 0.8: randomizes each "point" of the circle by 0.8. Since the circle has diameter 1, this changes the shape a lot. Lowering this number produces more circular looking shapes.
  • cornered 0.15: Join the random points by a straight line, but instead of lines joining at right angles to one-another, join the lines by a corner of radius 0.15.
  • randomized 0.1: Randomize all the points again, giving a scattered look. Leave this out if you want a smooth output.

Instead of starting with a circle, you can start with a more amoeba like shape to get more realistic output.

share|improve this answer

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.