TikZ-PGF – Drawing the Belt for a Chain of Gears

tikz-pgf

I want to draw like this

enter image description here

Gears I created based on rpapa's codes.

\documentclass{article}
\usepackage[dvipsnames,svgnames]{xcolor}
\usepackage{tikz}
\newcommand{\gear}[3]{%
  \def\modu{#1}
  \def\Zb{#2}
  \def\AngleA{#3}

  \pgfmathsetmacro{\Rpr}{\Zb*\modu/2}
  \pgfmathsetmacro{\Rb}{\Rpr*cos(\AngleA)}
  \pgfmathsetmacro{\Rt}{\Rpr+\modu}
  \pgfmathsetmacro{\Rp}{\Rpr-1.25*\modu}
  \pgfmathsetmacro{\AngleT}{pi/180*acos(\Rb/\Rt)}
  \pgfmathsetmacro{\AnglePr}{pi/180*acos(\Rb/\Rpr)}
  \pgfmathsetmacro{\demiAngle}{180/\Zb}
  \pgfmathsetmacro{\Angledecal}{(\demiAngle-2*\AnglePr)/2}

  \foreach \zz in{1,2,...,\Zb}{
    \draw[DarkSlateGray!70!Sepia]
    ({(\zz))/\Zb*360-\Angledecal}:\Rb)
    -- (\zz/\Zb*360-\Angledecal:\Rp)
    to[bend right=\demiAngle]
    (\zz/\Zb*360+\Angledecal:\Rp)
    --
    plot[domain=-0:\AngleT,smooth,variable=\t]
    ({{180/pi*(-\t+tan(180/pi*\t)) +\zz/\Zb*360+\Angledecal}:\Rb/cos(180/pi*\t)})
    % 
    to[bend right=\demiAngle]
    ({{180/pi*(\AngleT+tan(180/pi*-\AngleT)) +(\zz+1)/\Zb*360-\Angledecal}:
      \Rb/cos(180/pi*-\AngleT)})
    % 
    plot[domain=-\AngleT:-0,smooth,variable=\t]
    ({{180/pi*(-\t+tan(180/pi*\t)) +(\zz+1)/\Zb*360-\Angledecal}:\Rb/cos(180/pi*\t)});
  }
}

\begin{document}

\centering
\begin{tikzpicture}[scale=0.05]
\gear{3}{32}{20}
\path[fill=DarkSlateGray!70!Sepia] circle(40);
\draw[thick,double distance=2pt,fill=white] circle(20) ;
\begin{scope}[xshift=100cm,rotate=180/16]
\gear{3}{16}{20}
\path[fill=DarkSlateGray!70!Sepia] circle(17.5);
\draw[thick,double distance=2pt,fill=white] circle(8);
\end{scope}
\end{tikzpicture} 

\end{document}

How do I draw the belt?

Best Answer

An example using the tangent coordinate system and the math, calc and decoration libraries. The tangent coordinate system requires nodes, so I guess in a "proper" application with more fancy wheels they would need to be created invisibly.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc,math,decorations}
\pgfkeys{/pgf/decoration/links/.initial=50}
\pgfdeclaredecoration{chain links}{start}{
\state{start}[width=0pt, next state=draw,
  persistent precomputation={
    \pgfmathsetlengthmacro{\linklength}%
      {\pgfdecoratedpathlength/(\pgfkeysvalueof{/pgf/decoration/links})}%
  }]{}
\state{draw}[width=\linklength]{
  \draw [fill=gray!50] (-\linklength/4,-\linklength/4) 
  arc (270:90:\linklength/4)
  .. controls ++(\linklength/8,0) and ++(-\linklength/8,0)
  .. (0,\linklength/6)
  .. controls ++(\linklength/8,0) and ++(-\linklength/8,0)
  .. (\linklength/4, \linklength/4)
  arc (90:-90:\linklength/4)
  .. controls ++(-\linklength/8,0) and ++(\linklength/8,0)
  .. (0,-\linklength/6)
  .. controls ++(-\linklength/8,0) and ++(\linklength/8,0)
  .. (-\linklength/4, -\linklength/4);
  \draw 
    (-\linklength/4,0) circle [radius=\linklength/8]
    (\linklength/4,0) circle [radius=\linklength/8];
}
}
\begin{document}
\begin{tikzpicture}[wheel/.style={fill=gray!70, circle, minimum size=#1*2cm}]
\tikzmath{%
  coordinate \p;
  \p1 = (0,0); \p2 = (4,0);
  \r1 = 2; \r2 = 1;
  {
    \node [wheel=\r1] (big) at (\p1) {};
    \node [wheel=\r2] (little) at (\p2) {};
  }; 
  \p3 = (tangent cs:node=big, point={(little.north)});
  \a = atan2(\py3-\py1, \px3-\px1);  
}
\draw [decoration={chain links, links=40}, decorate] 
  ($(\p1)+(\a:\r1)$)  arc (\a:360-\a:\r1) --
  ($(\p2)+(-\a:\r2)$) arc (-\a:\a:\r2)    -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

And just a follow-up to John Kormylo's excellent answer, here is a gears pic. Note, that the pic specification uses unit-less numbers for gear size (diameter) and x-y coordinates to delay the conversion to points. This helps to avoid math overflow or unexpected output when the coordinates have units but the size does not (or vice versa).

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math,calc}
\tikzset{%
  set gear dots/.style={
    gear dots/.style={dash pattern=on 4pt off 4pt, dash phase=#1}},
  set gear dots=0pt,
  pics/gears/.style args={size #1 at (#2,#3) and size #4 at (#5,#6)}{code={
\tikzmath{%
  \r1 = #1/2; \r2 = #4/2;
  \gm = atan2(#3-#6, #2-#5);
  \th = acos((\r1 == \r2) ? 0 : (\r2-\r1) / veclen(#5-#2, #6-#3));
  coordinate \c, \t;
  \c1 = (#2, #3); \t1 = (\c1) + (360-\th+\gm:\r1);
  \c2 = (#5, #6); \t2 = (\c2) + (\th+\gm:\r2);
}
\draw [black!80, thick, fill=gray!25] (\c1) circle [radius=\r1];
\draw [black!80, thick, fill=gray!25] (\c2) circle [radius=\r2];
\draw [gray, ultra thick, postaction={draw=gray!50, gear dots, ultra thick}] 
  (\t2) arc (\th+\gm:360-\th+\gm:\r2) -- 
  (\t1) arc (360-\th+\gm:360+\th+\gm:\r1) -- cycle;
  }}}
\begin{document}
\foreach \i in {0,...,7}{
\tikz[set gear dots=\i]{
  \pic {gears={size 1 at (1,-1) and size 2 at (3,2)}};
  \pic {gears={size 1 at (-1,0) and size 1 at (-1,3)}};
  \pic {gears={size 0.5 at (-1,3) and size 1 at (3,2)}};
  \pic {gears={size 0.5 at (-1,0) and size 0.25 at (1,-1)}};
}}
\end{document}

enter image description here