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 want to use tikz to draw a golden spiral, growing clockwise, ideally (but not necessarily) superimposed over a set of golden rectangles (you all know the image I'm talking about). A little bit of searching led me to this code, which yields a counterclockwise spiral:

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.markings,calc}
\tikzset{nctopath/.style={
     to path=(\tikztostart) ..controls ($(\tikztostart)!1cm*#1!-90:(\tikztotarget)$) and 
        ($(\tikztotarget)!($(\tikztostart)!1cm*#1!-50:(\tikztotarget)$)!70:    (\tikztostart)$).. 
    (\tikztotarget)
    },
}
\begin{document}    
\begin{tikzpicture}
\def\totx{1}
\coordinate (n-1-1) at (0,0) {};
\foreach \x[count=\xi from 2, evaluate=\x as \temptotx using int(\x+\totx)] in {1,...,9}{
\draw[decoration={
    markings,mark=between positions 0 and 1 step 0.249 with {
            \coordinate (n-\x-\pgfkeysvalueof{/pgf/decoration/mark info/sequence number})     ;
        }
   },postaction=decorate
] 
(n-\x-1) arc (\x*90+180:(\x+1)*90+180:{(\temptotx)*3mm}) 
coordinate (n-\xi-1) 
\pgfextra{\xdef\totx{\temptotx}};
}

\end{tikzpicture}
\end{document}

The thing is that I'm still new to tikz and thus not sure what code here does what. My questions are:

  1. How do I reverse the growth direction?

  2. How do I set phi as the growth factor (which I don't think it is currently, just from looking at the resulting spiral)?

  3. How cumbersome would it be to add in the golden rectangles (i.e., would I have to draw each one individually, or is there some way to define a pattern)?

share|improve this question

3 Answers 3

up vote 43 down vote accepted

Basically, the same approach as JLDiaz but using a recursive macro and letting tikz scopes and transformations do all the work.

\documentclass[tikz, border=0.125cm]{standalone}
\begin{document}

\def\spiral#1{%
  \pgfmathparse{int(#1)}%
  \ifnum\pgfmathresult>0
    \draw [help lines] (0,0) rectangle ++(1,1);
    \begin{scope}[shift={(1,1)}, rotate=90, scale=1/1.6180339887]
      \spiral{#1-1}
    \end{scope}
    \draw [red] (0,0) arc (270:360:1);
  \fi
}

\tikz[scale=2]{\spiral{12}}

\end{document}

enter image description here

And perhaps...

\documentclass[border=0.125cm, tikz]{standalone}

\begin{document}

\def\spiral#1#2#3{%
  \pgfmathparse{int(#1)}%
  \ifnum\pgfmathresult>0
    \draw [help lines] (0,0) rectangle ++(1,1);
    \begin{scope}[shift={(1,1)}, rotate=#2, scale=1/#3]
      \spiral{#1-1}{#2}{#3}%
    \end{scope}
    \pgfmathparse{int(\a)}%
    \ifnum\pgfmathresult=0
      \draw [red] (0,0) -- (1,1);
    \else%
      \draw [red] (0,0) arc (270+45-#2/2:360-45+#2/2:{1/sqrt(2) / sin(#2/2)});
    \fi
  \fi
}

\foreach \a in {90,85,...,-90,-85,-80,...,85}{
 \tikz[scale=2]{\spiral{12}{\a}{1.6180339887}\useasboundingbox (-0.5,-0.5) rectangle (3.5,3.5);}
}

\end{document}

enter image description here

share|improve this answer
2  
+1 the spiral gets drawn on top of the squares, without need of layers. Smart! –  JLDiaz Nov 23 '13 at 19:06
8  
What a nice animation! –  juliohm Nov 23 '13 at 23:32
    
Whoa! How did you do the animation? –  crmdgn Nov 24 '13 at 16:03
    
@crmdgn gimp is ideal for this kind of thing. –  Mark Wibrow Nov 24 '13 at 18:57
    
As in gimp the photo editor? or is there a gimp TeX package? –  crmdgn Nov 24 '13 at 20:35

Code

Improved a little the code to make easier the explanations, and to put the "golden ratio rectangles" in a background layer. Explanations below the picture.

Updated after egreg's comments.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\thispagestyle{empty}
\usetikzlibrary{calc}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\newcommand\GoldenRatio{1.6180339887}
\newcommand\Side{10}
\newcommand\Sqrtwo{1.4142135624}

\begin{tikzpicture}[line cap=round]
\coordinate (origin) at (0,0);
\foreach \angle in {0,90,...,1000} {
  \coordinate (corner) at ($(origin)+(45+\angle:\Side*\Sqrtwo)$);
  \begin{pgfonlayer}{background}
      \draw[help lines] (origin) rectangle (corner);
  \end{pgfonlayer}
  \draw[very thick,red] (origin) arc(\angle-90:\angle:\Side);
  \coordinate (origin) at (corner);
  \pgfmathsetmacro{\Side}{\Side/\GoldenRatio}
  \xdef\Side{\Side}
}
\end{tikzpicture}
\end{document}

Result

Result

Explanations

The picture is built recursively, from a fundamental building block, which is a square containing a red arc.

The square is defined from two points. The first one is called origin, and initially is located at (0,0), but it will move in successive iterations of the loop. The second one is called corner, and its coordinates are dependent of those of origin in the following way:

  \coordinate (corner) at ($(origin)+(45+\angle:\Side*\Sqrtwo)$);

The expression +(45+\angle:\Side*\Sqrtwo) uses polar coordinates, relative to origin. The angle is 45 plus the "current angle" (initially zero), and the distance is the diagonal of the square whose side has \Side units of length.

Once origin and corner are known, the building block is drawn as (omitted in this case the background layer for clarity):

  \draw[help lines] (origin) rectangle (corner);
  \draw[very thick,red] (origin) arc(\angle-90:\angle:\Side);

In the first iteration, since \angle=0, \Side=10, this produces the following building block, whose side has 10 units of length:

Building block

Now, the neat trick is to update all the variables which define the building block, so that the next building block has:

  • Its origin at the previous block corner
  • Its \angle increased in 90 degrees
  • Its \Side reduced in the golden ratio.

This is the role of the next lines:

  \coordinate (origin) at (corner);
  \pgfmathsetmacro{\Side}{\Side/\GoldenRatio}
  \xdef\Side{\Side}

The following figure shows the two first iterations, and thus the two first building blocks. I decided to draw also in blue the vector which places the "corner" relative to the origin, to better understand the procedure:

Two steps

And so on, at each step the building block is reduced by the golden ratio, rotated 90 degrees, and shifted to the latest "corner".

share|improve this answer
    
I'll be damned. That's exactly what I need. Super curious to see the explanation, whenever you have time. –  crmdgn Nov 23 '13 at 15:44
    
@crmdgn Also note that what I have drawn is an approximation of a "true" golden spiral, as noted here –  JLDiaz Nov 23 '13 at 16:18
    
Very good answer; I have two remarks, though. Don't use \def, first of all, much less redefine \Phi in the open. Then, what's the sense of giving the golden ratio with three decimal digits and the square root of 2 with nineteen? –  egreg Nov 23 '13 at 16:19
    
@egreg What's the issue with \def and with defining \Phi? –  crmdgn Nov 23 '13 at 16:27
1  
@JLDiaz With \newcommand{\Phi}{1.618} you'd have been warned that \Phi is already defined. –  egreg Nov 23 '13 at 16:36

Just for fun with PSTricks. No recursively-invoked macro is used here. Instead, the next node is determined by the previous one in a loop.

Linear complexity

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

\pstVerb
{
    /R   5 def
    /P   {2 5 sqrt 1 add div} def
    /p   {1 P div} def
    /OmP {1 P sub} def
    /C   {2 sqrt mul 45 PtoC} def
}

\def\Atom#1{%
\begin{pspicture}(-4,-1)(6,6)
    \pnode(!p 1 sub R mul neg 0 ){A-1}
    \multido{\ic=0+1,\ip=-1+1}{#1}
    {%
        \nodexn{(A\ip)+(!\ic\space dup 1 sub P exch exp R mul OmP mul exch 90 mul PtoC)}{A\ic}
        \rput(A\ic){\rput{!90 \ic\space mul}(0,0){\psframe(!R P \ic\space exp mul C)}}
    }
    \pscustom[linecolor=red]{\multido{\ic=0+1}{#1}{\psarc(A\ic){!R P \ic\space exp mul}{!\ic\space 90 mul}{!\ic\space 90 mul 90 add}}}
\end{pspicture}}

\begin{document}
\multido{\i=0+1}{12}{\Atom{\i}}
\end{document}

enter image description here

Quadratic complexity

It is not recommended as creating the i-th node needs i iterations.

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

\pstVerb
{
    /R   5 def
    /P   {2 5 sqrt 1 add div} def
    /p   {1 P div} def
    /OmP {1 P sub} def
    /C   {2 sqrt mul 45 PtoC} def
}

\def\Atom#1{%
\begin{pspicture}(-4,-1)(6,6)
    \curvepnodes[plotpoints=#1]{0}{\the\numexpr#1-1\relax}
    {
        p 1 sub R mul neg 0 
        0 1 t
        {
          dup 1 sub P exch exp R mul OmP mul exch 90 mul PtoC
            3 -1 roll add 3 1 roll add exch 
        } for 
    }{A}
    \multido{\ic=0+1}{#1}{\rput(A\ic){\rput{!90 \ic\space mul}(0,0){\psframe(!R P \ic\space exp mul C)}}}
    \pscustom[linecolor=red]{\multido{\ic=0+1}{#1}{\psarc(A\ic){!R P \ic\space exp mul}{!\ic\space 90 mul}{!\ic\space 90 mul 90 add}}}
\end{pspicture}}

\begin{document}
\multido{\i=2+1}{12}{\Atom{\i}}
\end{document}

Closed form

In progress...

share|improve this answer
    
I will edit this answer later as I have many things to do right now. The quadratic complexity can be converted to be linear with temporary variables as explained by Christoph in another topic on this site. –  stalking is prohibited Nov 26 '13 at 22:14

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.