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 reproduce this kind of figure:

enter image description here

I'm wondering what's the best way to achieve that with TikZ.

My guess is to draw an element composed of a circle + a link and to link this element by specifying only an angle (since the distance is always the same).

Any suggestions?

share|improve this question
1  
Welcome to TeX.SX. –  Claudio Fiandrino Mar 31 '13 at 13:41
add comment

5 Answers

A very simple proof of concept example:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[fill] (0,0) circle (.5) -- ++(10:2) circle (.5) -- ++(-20:2) circle (.5);
\end{tikzpicture}
\end{document}

enter image description here

Of course one could do some very nice tweaks such as building an own style for the lines and circles, but the code above contains at least everything that is needed to reach your goal.

Depending on what you need exactly, it was also very easily possible to automate the generation of such a chain including for example random angles between the beads.

Here's a version using a \foreach to specify a list of angles:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\tikzset{bead/.style={circle,fill=black,inner sep=3pt}}

\draw node[bead] {} (0,0)
\foreach \angle in {10,40,50,-50,0,150,30,-60,45,45,0}
  { -- ++(\angle:1) node[bead] {}};
\end{tikzpicture}

\end{document}

enter image description here

And a version with relative angles (Qrrbrbirlbel suggested this version in chat and I like it more than the one I initially had):

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\tikzset{bead/.style={circle,fill=black,inner sep=3pt}}
\def\angle{0}

\draw node[bead] {} (0,0)
\foreach \stepangle[evaluate=\stepangle as \angle using \angle+\stepangle, remember=\angle] in {10,20,-30,-60,135,-20,-30,0}
  { -- ++(\angle:1) node[bead]{}};
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
3  
If you don't mind non-tikz solutions, I can provide an Asymptote example which lets to construct bead chains in a form like pos>0>45>-45>90>135. –  g.kov Mar 31 '13 at 16:11
3  
@g.kov I'd encourage answers using different tools. –  egreg Mar 31 '13 at 22:27
2  
@g.kov: It would be nice to have examples of different methods. I request you to make such answers like a tutorial type with more details so that we (atleast I) will start learning. Asymptote is superior in certain aspects. –  Harish Kumar Apr 1 '13 at 0:15
    
I added a version with a \foreach. Please feel free to roll-back my edit if you don't like it. –  Gonzalo Medina Apr 1 '13 at 1:32
    
@Harish Kumar: An asy version added. I tried to make it kind of a tutorial style. If something in the example needs a clarification, please let me know. –  g.kov Apr 1 '13 at 7:07
show 4 more comments

enter image description here

To fit the original request that a chain is built by specifying only angles, Asymptote provides an operator overloading. An overloaded operator > pair operator>(pair pos=(0,0), real phi) takes a position on the left and an angle on the right, calculates a proper transform (combined rotation and shift) and calls a procedure bead that actually draws the bead with radial shading and a link. Thus the chains are constructed either as pos=pos>0>45>-45>90>135 which updates the position, or just pos>0>45>-45>90>135; pos>90>90>90; to draw several branches from the same origin. Note that a numeric comparison with > still works, since it corresponds to a different signature of parameters. beads.asy:

size(300,300);
real linkLen=1, linkWidth=2pt; 
real rl=2+linkLen;              // distance between beads
guide g=(1,0)--(1+linkLen,0);   // a link
pen beadColor=orange;
pen linkColor=beadColor;
void bead(transform t){  
  draw(t*g,linkColor+linkWidth);
  radialshade(t*unitcircle,
    beadColor,shift(t)*(-0.4,0.3),0.01
   ,black,shift(t)*(-0.4,0.3),1.5); 
}
pair operator>(pair pos=(0,0), real phi){
  transform t=shift(pos.x,pos.y)*rotate(phi);
  bead(t); // draw a bead with a link
  pos+=rl*(Cos(phi),Sin(phi)); // Sin, Cos - in degrees, sin, cos - in radians
  return pos;
}; 

pair pos=(0,0); // start point

if(exp(1)>pi){ // note that ">" still works the usual way to compare numbers
  // this branch is skipped 
}else{
  pos=pos>0>45>-45>90>135; // draw a bead chain and update the position
  pos>0>45>-45>90>135;     // continue the chain without updating the start position
  beadColor=lightyellow;
  linkColor=lightblue;
  pos>90>90>90;           // draw another branch from saved position, with different colours
}

A standalone pdf is produced by asy -f pdf beads.asy

Edit: This is an inline version, beads-inline.tex:

\documentclass[10pt,a4paper]{article}
\usepackage{lmodern}
\usepackage{soul}
\usepackage{caption}
\usepackage[inline]{asymptote}
\def\asydir{}
\begin{asydef}
// Global Asymptote definitions 
real linkLen=1, linkWidth=2pt; 
real rl=2+linkLen;              // distance between beads
guide link=(1,0)--(1+linkLen,0);   // a link
pen beadColor=orange;
pen linkColor=beadColor;
void bead(transform t){  
  draw(t*link,linkColor+linkWidth);
  radialshade(t*unitcircle,
    beadColor,shift(t)*(-0.4,0.3),0.01
   ,black,shift(t)*(-0.4,0.3),1.5); 
}
pair operator>(pair pos=(0,0), real phi){
  transform t=shift(pos)*rotate(phi);
  bead(t); // draw a bead with a link
  pos+=rl*(Cos(phi),Sin(phi)); // Sin, Cos - in degrees, sin, cos - in radians
  return pos;
}; 
pair pos;
\end{asydef}

\begin{document}

\newcommand\hi[1]{\bf Hello \st{Word} #1!}

\center
\captionof{figure}{Example of bead chain building.}
\begin{asy}
  size(150,150);
  pos>0>60>0>70;   
  beadColor=lightyellow;
  pos>0>-60>0>-70;
  pos=  pos>0>0>0>0;     
  label("\textbf{Example}",pos,SE);
\end{asy}

\center
\captionof{figure}{Another example of bead chain building.}
\begin{asy}
  size(150,150);
  beadColor=lightyellow;
  linkColor=lightblue;
  pos=pos>90>42>0>0>0>0>0>0>-130;   
  label(
     "\parbox{8cm}{"
     "The following command \texttt{\textbackslash hi} is defined \\"
     +"in the main \LaTeX\ document:\\"
     "\hi{\LaTeX}}"
     ,pos);
\end{asy}

\end{document}

To process it with latexmk, create file latexmkrc:

sub asy {return system("asy '$_[0]'");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");

and run latexmk -pdf beads-inline.tex. The result looks like

enter image description here

For more details consult the manual at: asymptote development page at sourceforge or, in case if you happened to be a lucky TeX Live user, just type texdoc asymptote.

share|improve this answer
    
Thank you for Asymptote side of graphics typesetting. –  texenthusiast Apr 1 '13 at 6:58
2  
@texenthusiast: Perhaps, the Asymptote just needs more ready-to-use templates to become more popular. –  g.kov Apr 1 '13 at 7:25
    
Nice. Is it possible to compile this from within the .tex file?! Also, (I was wondering looking at your previous answers) how do you find out the coordinates? Is there any short cut?. It will be nice if you add the links to reference/learning material. +1 indeed. –  Harish Kumar Apr 1 '13 at 15:46
    
@Harish Kumar: The main documentation is at http://asymptote.sourceforge.net/asymptote.pdf. If you mean the bead coordinates, in the example they are stored in pos variable and update happens in a line pos+=rl*(Cos(phi),Sin(phi));. –  g.kov Apr 1 '13 at 19:00
add comment

With PSTricks.

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}

\def\X(#1){#1}
\def\Y(#1){3+2*sin(#1)}

\psset{algebraic,showpoints,dotscale=3}

\begin{document}

\begin{pspicture}(-1,-1)(7,6)
    \psparametricplot[plotpoints=10]{-0.5}{6.5}{\X(t)|\Y(t)}
\end{pspicture}
\end{document}

\end{document}

Animation

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot}

\def\X(#1){#1}
\def\Y(#1){3+2*sin(#1)}

\psset{algebraic,showpoints,dotscale=3}

\begin{document}

\multido{\i=2+1}{21}{%
\begin{pspicture}(-1,-1)(7,6)
    \psparametricplot[plotpoints=\i]{-0.5}{6.5}{\X(t)|\Y(t)}
\end{pspicture}}
\end{document}

\end{document}

The latest edit

If you need equally-spaced beads, see the following:

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}

\begin{document}

\begin{pspicture}[showgrid](-1,-1)(8,3)
    \psStartPoint(0,0)
    \psforeach{\i}{10,40,50,-50,0,150,30,-60,45,45,0}{\psVector[arrows=-*](1;\i)}
\end{pspicture}

\end{document}

or

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}

\begin{document}

\begin{pspicture}[showgrid](-1,-1)(8,3)
    \pnode(0,0){A}
    \psforeach{\i}{10,40,50,-50,0,150,30,-60,45,45,0}{
    \pnode[!1 \i\space PtoC](A){B}
    \pscircle*(B){4pt}
    \psline(A)(B)
    \pnode(B){A}
    }
\end{pspicture}

\end{document}
share|improve this answer
    
What is the PSTricks equivalent to the \foreach solution by Benedikt Bauer/Gonzalo Medina, i.e. fixed width and specified angles? –  Qrrbrbirlbel Apr 1 '13 at 1:37
    
@Qrrbrbirlbel: well done! –  I am who I say I am Apr 1 '13 at 2:23
    
There is no more technique with \pspolylineticks which is very sophisticated but its documentation is really confusing to grasp. –  I am who I say I am Apr 2 '13 at 1:02
add comment

Another TikZ solution that uses ducks turtles! :)

The turtle library is well-explained in its own chapter in the PGF manual, chapter 54/59 “Turtle Graphics Library”:

This little library defines some keys to create simple turtle graphics in the tradition of the Logo programming language. These commands are mostly for fun, but they can also be used for more “serious” business.

Keys

  • bead node style: a node style for the beads (→ Benedikt Bauer’s answer);
  • bead style: an insert path that makes it easy to include a bead node, it accepts one optional parameter to customize the bead node;
  • bead path style: this is a to path that includes a bead node at the start coordinate and your usual line to -- to the target coordinate;
  • turtle/beads style: this install all necessary styles inside the turtle key:
    • the how style is set to the bead path style, and
    • the starting direction is set by turning the turtle to the right

Now we would be able to say

\draw (0,0) [turtle={beads, right=10, forward, left=20, forward, …}];

and so on and it would work quite well, but the lazy turtle just wants to know the (relative) directions it has to head.

This is why I defined an additional turn and step style in the turtle path.
When used with the .list handler we can process a comma-delimited list of (relative) angles very easily:

\draw (0,0) [turtle={beads,turn and step/.list={10,20,-30,-60,135,-20,-30,0}}] [bead];

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{turtle}
\tikzset{
    bead node/.style={circle,fill=black,inner sep=3pt},
    bead path/.style={to path={ [bead] -- (\tikztotarget)}},
    bead/.style={insert path={node[bead node]{}}},
    turtle/beads/.style={how/.style={bead path},right},
    turtle/turn and step/.style={left=#1,forward}
}
\begin{document}
\begin{tikzpicture}[turtle/distance=1cm]
\draw (0,0) [turtle={beads,turn and step/.list={10,20,-30,-60,135,-20,-30,0}}] [bead];
\end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
add comment

Interesting question for me because tkz-graph is a possibility o draw this kind of graph but I created the possibility to add vertices with polar coordinates, I need to use the origin and not the last vertex. So I need to find a trick to build the graph.

\documentclass[margin=.25cm]{standalone}
\usepackage{tkz-graph}

\begin{document}
\begin{tikzpicture}
\GraphInit[vstyle=Art]% Init the graph and choice a style
\SetVertexNoLabel% no label
\Vertex{A} 
\foreach \a in {45,10,30,-20,0,-60,-40,-45,-10,-90,+20,0,60,-40}{%
\begin{scope}[shift=(A)]% polar from the last vertex
    \Vertex[a=\a , d=1 cm]{B}
    \Edge[style={thick,double=black,double distance=1pt}](A)(B) 
    \pgfnoderename{A}{B}% rename the node, useful macro here
\end{scope}
}
\end{tikzpicture} 

\end{document}

enter image description here

Possible to get a shorter code:

\newcommand{\newVertex}[1]{%
\begin{scope}[shift=(A)]
    \Vertex[a=#1 , d=1 cm]{B} 
\end{scope}    
}

and

\foreach \a in {45,10,30,-20,0,-60,-40,-45,-10,-90,+20,0,60,-40}{%
    \newVertex{\a}
    \Edge[style={thick,double=black,double distance=1pt}](A)(B) 
    \pgfnoderename{A}{B}
}
share|improve this answer
add comment

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.