6

I'm trying to redraw this image (source) in TikZ.

golden triangles in a logarithmic spiral

Here is my code for a triangle with an arbitrary length of the base (just straight forward construction):

\begin{tikzpicture}[x=1mm, y=1mm]

    % Base length
    \def\l{40}      

    \draw[line width=0.1mm] (0, 0) -- (\l, 0) -- (0.5*\l, {0.5*\l*tan(72)}) -- cycle;

    % y = tan(36)x              
    \draw[line width=0.1mm, domain=0:{0.25*(1+sqrt(5))*\l}] plot(\x, {tan(36)*\x});

    % y = tan(144)x - tan(144)*\l
    \draw[line width=0.1mm, domain={0.5*\l}:\l] plot(\x, {tan(144)*\x - tan(144)*\l});

    % y = tan(252)x + (tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*(0.25*(1+sqrt(5))*\l)
    \pgfmathsetmacro{\p}{((tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*(0.25*(1+sqrt(5))*\l) + tan(144)*\l)/(tan(144) - tan(252))}
    \pgfmathsetmacro{\q}{0.25*(1+sqrt(5))*\l}               
    \draw[line width=0.1mm, domain={\p}:{\q}] plot(\x, {tan(252)*\x + tan(36)*0.25*(1+sqrt(5))*\l -  tan(252)*0.25*(1+sqrt(5))*\l});

    % y = tan(36)*0.5*\l
    \pgfmathsetmacro{\p}{(tan(36)*0.5*\l + tan(252)*0.25*(1+sqrt(5))*\l - tan(36)*0.25*(1+sqrt(5))*\l)/(tan(252))}
    \draw[line width=0.1mm, domain={0.5*\l}:{\p}] plot(\x, {tan(36)*0.5*\l});

    % y = tan(108)x + ((tan(144)*(tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*0.25*(1+sqrt(5))*\l + tan(144)*\l)/(tan(144) - tan(252)) - tan(144)*\l) - tan(108)*(tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*0.25*(1+sqrt(5))*\l + tan(144)*\l)/(tan(144) - tan(252)))       
    \pgfmathsetmacro{\m}{tan(108)}
    \pgfmathsetmacro{\b}{((tan(144)*(tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*0.25*(1+sqrt(5))*\l + tan(144)*\l)/(tan(144) - tan(252)) - tan(144)*\l) - tan(108)*(tan(36)*0.25*(1+sqrt(5))*\l - tan(252)*0.25*(1+sqrt(5))*\l + tan(144)*\l)/(tan(144) - tan(252)))}   
    \pgfmathsetmacro{\p}{(tan(36)*0.5*\l - \b)/\m}      
    \pgfmathsetmacro{\q}{(-\b - tan(144)*\l)/(\m - tan(144))}       
    \draw[line width=0.1mm, domain={\p}:{\q}] plot(\x, {\m*\x + \b});
\end{tikzpicture}

"A bit" messy, but it works. So, the problem is to put the spiral with right parameters at the right place.

I've calculated the coordinates of an intersection point (the pole of the spiral) of two red lines in original image for base length 40 and shifted a rotated spiral:

    \pgfmathsetmacro{\cx}{(-sqrt(0.5*(5+sqrt(5)))*20 - (1/3)*sqrt(5+2*sqrt(5))*40)/(((-1/3)*sqrt(5+2*sqrt(5)) - sqrt(0.5*(5+sqrt(5)))))}
    \pgfmathsetmacro{\cy}{(-1/3)*sqrt(5+2*sqrt(5))*((-sqrt(0.5*(5+sqrt(5)))*20 - (1/3)*sqrt(5+2*sqrt(5))*40)/(((-1/3)*sqrt(5+2*sqrt(5)) - sqrt(0.5*(5+sqrt(5)))))) + (1/3)*sqrt(5+2*sqrt(5))*40}
    \pgfmathsetmacro{\a}{(5/(3*pi))*ln((1+sqrt(5))/2)}
    \begin{scope}[rotate around={-270:(\cx, \cy)}]
        \draw[line cap=round, line width=0.2mm, domain=-3*pi:4*pi, variable=\t, samples=1000]
            plot ({\cx + 2.04666*exp(\a*\t)*cos(deg(\t))}, 
                                            {\cy - 2.04666*exp(\a*\t)*sin(deg(\t))});
    \end{scope}

output image

The output looks pretty well but the estimated parameter 2.04666 annoys me. Is there any way to calculate it? Is there any better way to place the right spiral at the right place?

4
  • That seems to be much more of a math question then a TeX one to me? Nov 25, 2015 at 11:15
  • That number is the phase of the spiral. It depends on how big your triangles are, which is quite arbitrary. It could have a closed form. But since everything is eventually a floating number, one can simply draw a picture in Geogebra and measure it.
    – Symbol 1
    Nov 25, 2015 at 16:40
  • 1
    Let A be a complex number representing the point on the top and O a complex number representing the center of the spiral. Then the number comes from |A-O|/exp(\a*arg(A-O)). Since you can express A=(0.5*\l, {0.5*\l*tan(72)}) and O=(\cx,\cy) now you can express 2.0466
    – Symbol 1
    Nov 25, 2015 at 16:52
  • Sure. It was a silly question from me. As I see now my problem was not this distance but the missing rotation of the spiral counterclockwise. Nov 26, 2015 at 9:43

2 Answers 2

6

I drew the spiral backwards, which I guess is the wrong way to do it.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc,intersections,math}
\begin{document}
\begin{tikzpicture}[line join=round, line cap=round, x=1pt, y=1pt]
\tikzmath{%
  coordinate \a, \b, \c, \o;
  int \i;
  \g = (1 + sqrt(5)) / 2;
  \a = (0,0);
  \b = (100,0);
  for \i in {1,...,6}{
    if (\i > 1) then {
      \a = (\b);
      \b = ($(\b)!1-1/\g!(\c)$);
    };
    \n = veclen(\bx-\ax, \by-\ay) * \g;
    \c = ($(\b)!\g!-72:(\a)$);
    {
      \fill [draw=black!50, fill opacity=1/10] 
        (\a) coordinate (a-\i) --
        (\b) coordinate (b-\i) --
        (\c) coordinate (c-\i) -- cycle;
    };
  };
}

\draw [red, dashed, name path=A] ($(a-1)!0.5!(c-1)$) -- (b-1);
\draw [red, dashed, name path=B] ($(a-2)!0.5!(c-2)$) -- (b-2);
\path [name intersections={of=A and B, by=O}];
\tikzmath{%
  \c1 = (c-1);
  \c2 = (c-2);
  \o = (O);
  \r1 = veclen(\cx1-\ox, \cy1-\oy);
  \r2 = veclen(\cx2-\ox, \cy2-\oy);
  \th1 = Mod(atan2(\cy1-\oy, \cx1-\ox), 360);
  \th2 = Mod(atan2(\cy2-\oy, \cx2-\ox), 360);
  \ph = \th2 > \th1 ? \th2 - \th1 : \th1 - \th2;
  \k = ln(1/\g)/\ph;
  \n = 20 * \ph;
}
\draw [blue!50!cyan, shift=(O)] 
  plot [smooth, domain=0:\n, samples=200, variable=\t]
    (\th1+\t:{\r1*exp(\k*\t)});
\end{tikzpicture}
\end{document}

enter image description here

1
  • That's a really nice piece of code with much to learn from it. Thank you! Nov 26, 2015 at 9:44
4

One code golfing solution ;)

\documentclass[tikz,border=7mm]{standalone}
\def~{(36:1)--(0,0)--(1,0)edge[bend left=54,blue](0,0)
      [shift={(1,0)},rotate=108,scale=0.61803398875]}
\begin{document}
  \tikz[scale=4]\draw~~~~~~;
\end{document}

enter image description here

Edit: A "better" approximation using arc in place of edge is :

\documentclass[tikz,border=7mm]{standalone}
\def~{(0,0)edge[black](36:1)edge[black](1,0)arc(-144:-36:0.61803398875)       
      [shift={(1,0)},rotate=108,scale=0.61803398875]}
\begin{document}
  \tikz[blue,scale=3]\draw~~~~~~;
\end{document}

The "exact" spiral in this case can be drawn with :

\draw[red,shift={(0.675186453011,0.333224435406)}] 
    plot[domain=-pi:3*pi,samples=300] (\x r:{0.379556295255/exp(0.255290802108*\x)});

And if we superpose this we can see the approximation error.

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .