5

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?

  • That seems to be much more of a math question then a TeX one to me? – Tom Bombadil Nov 25 '15 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 '15 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 '15 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. – GeMir Nov 26 '15 at 9:43
5

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

  • That's a really nice piece of code with much to learn from it. Thank you! – GeMir Nov 26 '15 at 9:44
3

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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