67

I am trying to create a gear in TikZ in which the number of spikes can be determined and the size as well. I was looking through the pgfmanual and stumbled upon the decorations section and I tried a piece of code there. Here is what I have so far:

\documentclass[letterpaper]{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
\begin{document}
\pgfdeclaredecoration{example}{initial}
{
\state{initial}[width=20pt]
{
\pgfpathlineto{\pgfpoint{0pt}{5pt}}
\pgfpathlineto{\pgfpoint{5pt}{5pt}}
\pgfpathlineto{\pgfpoint{5pt}{-5pt}}
\pgfpathlineto{\pgfpoint{10pt}{-5pt}}
\pgfpathlineto{\pgfpoint{10pt}{5pt}}
}
\state{final}
{
\pgfpathlineto{\pgfpointdecoratedpathlast}
}
}
\tikz[decoration=example]
{
\draw [red,decorate] (0,0) circle (1cm);
}
\end{document}

which yields:

enter image description here

Of course the above is not satisfactory. Is there a way a gear can be drawn in TikZ or any other graphics package?

Update: For those interested in ready made svg images, the NounProject provides some sample files. Follow this link: Engrenages.

7
  • Even after reading the excellent answers below I still feel like the "best" answer would use TikZ decorations. Jun 12, 2012 at 19:08
  • 2
    The "engrenages" pictures from NounProject are not realistic! Jun 30, 2012 at 18:17
  • @PolGab Guess so, if you are looking at it from a technical perspective. :)
    – azetina
    Jul 2, 2012 at 13:54
  • @azetina: Ok. So, specify in your question that you do not want necessarily a realistic drawing. Jul 2, 2012 at 14:24
  • 1
    Not in TikZ, but still interesting.
    – user10274
    May 22, 2014 at 9:06

9 Answers 9

82

You need to adapt the only line to draw the picture. The rotation here is 360/10. It's possible to modify the length of arcs, the type of teeth.

\documentclass[11pt]{scrartcl}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\draw[thick]
\foreach \i in {1,2,...,10} {%
  [rotate=(\i-1)*36] 
 (0:2)  arc (0:18:2) {[rounded corners=2pt] -- ++(18: 0.3)  arc (18:36:2.3) } -- ++(36: -0.3) 
};
\end{tikzpicture}
\end{document} 

enter image description here

update

How to modify :

  1. number of teeths : n

  2. radius intern circle r1

  3. radius extern circle r2

  4. rotation = 360/n

  5. first arc start angle =0 end angle= arc(0:a:r1)

  6. second arc start angle =a+b end angle=<360/n-b> arc(a+b:360/n-b:r2)

  7. line between arcs -- (a+b:r2)

  8. last line -- (360/n:r1)

    \begin{tikzpicture}
    \draw[thick]
    \foreach \i in {1,2,...,10} {%
       [rotate=(\i-1)*36]  (0:2)  arc (0:12:2) -- (18:2.4)  arc (18:30:2.4) --  (36:2)
     };
    \end{tikzpicture} 
    

enter image description here

With a macro

\documentclass[11pt]{scrartcl}
\usepackage{tikz}

% #1 number of teeths
% #2 radius intern
% #3 radius extern
% #4 angle from start to end of the first arc
% #5 angle to decale the second arc from the first 

\newcommand{\gear}[5]{%
\foreach \i in {1,...,#1} {%
  [rotate=(\i-1)*360/#1]  (0:#2)  arc (0:#4:#2) {[rounded corners=1.5pt]
             -- (#4+#5:#3)  arc (#4+#5:360/#1-#5:#3)} --  (360/#1:#2)
}}  


\begin{document}
 \begin{tikzpicture}
   \draw[thick] \gear{18}{2}{2.4}{10}{2};
 \end{tikzpicture}  
\end{document} 

enter image description here

With a adjusted macro

...you can also use \draw[fill]

\documentclass[11pt]{scrartcl}
\usepackage{tikz}

% #1 number of teeths
% #2 radius intern
% #3 radius extern
% #4 angle from start to end of the first arc
% #5 angle to decale the second arc from the first
% #6 inner radius to cut off

\newcommand{\gear}[6]{%
  (0:#2)
  \foreach \i [evaluate=\i as \n using {\i-1)*360/#1}] in {1,...,#1}{%
    arc (\n:\n+#4:#2) {[rounded corners=1.5pt] -- (\n+#4+#5:#3)
    arc (\n+#4+#5:\n+360/#1-#5:#3)} --  (\n+360/#1:#2)
  }%
  (0,0) circle[radius=#6] 
}
\begin{document}
 \begin{tikzpicture}
   \fill[even odd rule] \gear{18}{2}{2.4}{10}{2}{1};
 \end{tikzpicture}
\end{document}

enter image description here

5
  • 1
    @Jake Yes it's possible to modify but I don't know how to construct a real gear :( . I added an update. Jun 6, 2012 at 7:59
  • 1
    @Altermundus: Very nice code, as usual. :) In response to your comment: I am not a specialist, but at the university I had an assignment to design a gearbox. I remember that the sides of the teeth had to be involutes (evolvents) of a circle to reduce friction I believe. Another tiny detail: you never have sharp corners where mechanical stress can accumulate. That's one reason why ship or plane windows are circular (rounded corners). The wikipedia page on gears seems to be quite exhaustive. :)
    – Count Zero
    Jun 6, 2012 at 8:27
  • 1
    @CountZero Thanks for the explanations but I prefer pure geometry with mathematics. Perhaps oil or lubricant is necessary with my gears ! I added some arguments now to help the user to create a real gear. Jun 6, 2012 at 8:42
  • see the path with involute below
    – rpapa
    Jun 6, 2012 at 13:47
  • How can you make the gears smaller so they could fit in a chapter title?
    – Jeel Shah
    Mar 10, 2013 at 12:47
33

voici une solution plus conforme à la représentation d'une roue dentée avec developpante de cercle il sufit de préciser le nombre de dents, le module, l'angle de pression pour obtenir le tracé j'ai malgré tout simplifié le tracé pour les cercles de tetes et de pied

here is a solution more in line with the representation of a gear with involute sufit it specify the number of teeth, module, pressure angle to get the lay I still simplified the plot for circle heads and feet

Attention: le script ci-dessous ne fonctionne qu'avec PGF 2.1, version pgf 3 à la suite

Warning : this first script run only with pgf2.1

\documentclass[11pt]{scrartcl}
\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}

%   \draw[dashed] (0,0) circle (\Rpr);
%   \draw[red,dashed] (0,0) circle (\Rb);
%     \draw[dashed] (0,0) circle (\Rt);
%            \draw[dashed] (0,0) circle (\Rp);
\foreach \zz in{1,2,...,\Zb}{
         \coordinate(e\zz) at (\zz/\Zb*360+\Angledecal:\Rb);
         \draw[domain=-0:\AngleT,smooth,variable=\t,thick]
plot ({{180/pi*(-\t+tan(180/pi*\t)) +\zz/\Zb*360+\Angledecal}:\Rb/cos(180/pi*\t)})coordinate(d\zz);
         \coordinate(g\zz) at ({(\zz))/\Zb*360-\Angledecal}:\Rb);
         \draw[domain=-0:-\AngleT,smooth,variable=\t,thick]
plot ({{180/pi*(-\t+tan(180/pi*\t)) +(\zz+1)/\Zb*360-\Angledecal}:\Rb/cos(180/pi*\t)})coordinate(f\zz);
\draw[blue] (d\zz) to[bend right=\demiAngle] (f\zz);

\draw[rounded corners=\modu](e\zz)  -- (\zz/\Zb*360+\Angledecal:\Rp) to[bend left=\demiAngle]  (\zz/\Zb*360-\Angledecal:\Rp)  -- (g\zz);
}
}

\begin{document}

\begin{tikzpicture}[scale=0.2]
\gear{3}{15}{20}
\begin{scope}[xshift=40.5cm,rotate=180/12]
\gear{3}{12}{20}
\end{scope}
\end{tikzpicture}

\end{document} 

Script pour/for PGF3

 \newcommand{\gear}[4][]{%
 \def\modu{#2}
 \def\Zb{#3}
 \def\AngleA{#4}

 \pgfmathsetmacro{\Rpr}{\Zb*\modu/2}

\pgfmathsetmacro{\Rb}{\Rpr*cos(\AngleA)}
\pgfmathsetmacro{\Rt}{\Rpr+\modu}
\pgfmathsetmacro{\Rp}{\Rpr-1.25*\modu}
\pgfmathsetmacro{\AngleT}{sqrt(\Rt^2/\Rb^2-1)}

%\pgfmathsetmacro{\AnglePr}{pi/180*acos(\Rb/\Rpr)}
\pgfmathsetmacro{\AnglePr}{180/pi*sqrt(\Rpr^2/\Rb^2-1)}
\pgfmathsetmacro{\demiAngle}{180/\Zb}
\pgfmathsetmacro{\Angledecal}{(\demiAngle+0.075*\AnglePr)/2}%


\def\xxt{\Rb*(cos(\t r)+\t*sin(\t r))}
\def\yyt{\Rb*(sin(\t r) - \t*cos(\t r))}

\foreach \zz in{1,2,...,\Zb}{
         \coordinate(e\zz) at (\zz/\Zb*360+\Angledecal:\Rb);
         \draw[fill](e\zz)circle(0.1);
         \draw[domain=-0:\AngleT,smooth,variable=\t,thick,green,#1]
plot ({atan2(\xxt,\yyt)-90+\zz/\Zb*360+\Angledecal}:{\Rb*sqrt(1+\t^2)}  )coordinate(f\zz);

         \coordinate(g\zz) at ({(\zz+1))/\Zb*360-\Angledecal}:\Rb);
         \draw[domain=-0:\AngleT,smooth,variable=\t,thick,green,#1]
plot ({atan2(\xxt,-\yyt)-90+(\zz)/\Zb*360-\Angledecal}:{\Rb*sqrt(1+\t^2)}  )coordinate(d\zz);

\draw[#1] (f\zz) to[bend left=\demiAngle] (d\zz);

\draw[rounded corners=\modu,#1](e\zz)  -- (\zz/\Zb*360+\Angledecal:\Rp) to[bend right=\demiAngle]  ({(\zz+1)/\Zb*360-\Angledecal}:\Rp)  -- (g\zz);
}
}

\begin{tikzpicture}[scale=0.15]
\gear[red,ultra thick]{2}{15}{20}
\draw[red,ultra thick] (0,0) coordinate(O1)node[below left]{$O_1$}circle (1);
\draw[thin,red,dashed](O1) circle (15);
\begin{scope}[xshift=27cm,rotate=180/12]
\gear[blue,ultra thick]{2}{12}{20}
\draw[blue,ultra thick] (0,0)coordinate(O2)node[below left]{$O_2$} circle (1);
\draw[thin,blue,dashed](O2) circle (12);
\end{scope}
\draw[thin,black,dashed] (O1) --++(-18,0) --(15,0) coordinate(I) node[below right]{$I$}-- (O2) --++(18,0);
\draw[thin,black,dashed] (O1)--+(0,18)--+(0,-18);
\draw[thin,black,dashed] (O2)--+(0,18)--+(0,-18);
\draw[thin,black] (I) -- +(70:15)--+(-110:15);
\draw[thin,black] (I) --+(70:12)coordinate(aa)-- +(-70:15)--+(110:15);
\draw[thin,black] (I) -- +(-90:15)--+(90:12)coordinate(bb)--+(90:15);
\draw[-latex] (bb) to [bend left=10] node[above]{$\alpha$} (aa);
\draw (d1) -- ++(1,1);
\end{tikzpicture}

enter image description here

5
  • 1
    Merci monsieur. Very interesting indeed!
    – azetina
    Jun 6, 2012 at 13:51
  • 5
    Very beautiful solution! Jun 6, 2012 at 15:33
  • 1
    The unit of \demiAngle is degree. The unit of \AnglePr is radian. What is the unit of \Angledecal? Jan 10, 2014 at 18:35
  • 1
    Mise à jour avec prise en compte de la modification de la commande atan de pgf3
    – rpapa
    May 22, 2014 at 8:41
  • Do these gears work when cut by a laser from acrylic sheet?
    – bkarpuz
    Dec 29, 2021 at 13:16
23

It's probably easiest to use \foreach to repeat an exactly calculated path for each tooth. Maybe something like the following (though I don't know how exactly gears have to be shaped to work correctly).

\documentclass{article}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \def\teeth{10}
    \def\innerRadius{1cm}
    \def\outerRadius{1.3cm}
    \pgfmathsetmacro\angle{360/(2*\teeth)}

    \foreach \i in {1,2,...,\teeth} {
        \draw ({\i*\angle*2}:\innerRadius)
            -- ({(2*\i+0.5)*\angle}:\outerRadius) 
            arc [radius=\outerRadius, start angle={(2*\i+0.5)*\angle}, end angle={(2*\i+.9)*\angle}]
            -- ({(2*\i+1.4)*\angle}:\innerRadius) 
            arc [radius=\innerRadius, start angle={(2*\i+1.4)*\angle}, end angle={(2*\i+2)*\angle}];
    }
\end{tikzpicture}
\end{document}

result

1
  • I guess with this one can define several types of teeth for the gears and have a sort of template implementation to get several types. Am I right?
    – azetina
    Jun 6, 2012 at 1:27
18

Here, an adaptation from rpapa's solution where each tooth is drawn by a single path. My goal is to draw entire gear by a single path. But, at this time, it seems that it is impossible to use plot into a foreach into a path!

\documentclass{standalone}
\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
    ({(\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}

\begin{tikzpicture}[scale=0.2]
\gear{3}{15}{20}
\begin{scope}[xshift=40.5cm,rotate=180/12]
\gear{3}{12}{20}
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

18

Paul Gaborit's solution mentions that it was impossible to use plot inside a foreach inside a \path. This seems to have changed, so here's an adapted solution that is one closed shape. Also, we now have pics!

\documentclass[tikz,margin=10pt]{standalone}

\tikzset{pics/gear/.style n args={3}{
    code={
        \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}

        \path[pic actions] foreach \zz in{1,...,\Zb}{
            \ifnum\zz=1
                % don't use a lineto in the first iteration
                (\zz/\Zb*360-\Angledecal:\Rp)
            \else
                -- (\zz/\Zb*360-\Angledecal:\Rp)
            \fi
            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)})
        } -- cycle;
    }
}}

\begin{document}
    \begin{tikzpicture}
        % observations:
        %
        %  - param #1 and #3 must be equal for gears to mesh
        %  - the required distance is (#2_1 + #2_2) * #1 / 2
        %  - for odd numbers of teeth, gears on a horizontal axis fit without rotation

        \pic[draw,fill=red!20!white]                     at (0,0)   {gear={0.50}{17}{15}};
        \pic[draw,fill=red!20!white]                     at (6,0)   {gear={0.50}{ 7}{15}};

        \pic[draw,fill=blue!20!white,rotate=-60 + 90/11] at (0,0)   {gear={0.25}{11}{20}};
        \pic[draw,fill=blue!20!white,rotate=-60 - 90/29] at (-60:5) {gear={0.25}{29}{20}};

        \foreach \p in {(0,0),(6,0),(-60:5)} \fill \p circle (3pt);
    \end{tikzpicture}
\end{document}

output

Any suggestions on how to remove the ugly \ifnum are welcome.

5
  • 2
    really nice result ! Mar 17, 2016 at 17:48
  • 1
    I don't understand the required distance formula: (#2_1 + #2_2) / (#1 * #2). For the red gears, I take it that #2_1+#2_2 is 17+7=24. But what do #1 and #2 stand for ?
    – wilk
    Mar 14, 2017 at 16:48
  • 1
    @wilk Good question, it's been a while. Seems like the formula is simply wrong. From new experiments, it seems that it's (#2_1 + #2_2) * #1 / 2. #2_1 stands for the second parameter of the first gear (i.e. 17), and #1 is the common first parameter of the two gears (i.e. 0.5).
    – wrtlprnft
    Mar 15, 2017 at 17:20
  • That's a great answer. But could you maybe elaborate and document the three parameters of the 'gears' pic? It is not immediately obvious what those parameters control (and what their valid arguments are).
    – Flow
    Jun 30, 2022 at 8:37
  • @Flow Well, I didn't create the gear code, that's from Paul Gaborit's answer. #2 is clearly the number of teeth. From the names \modu and \AngleA, it seems like #1 is the module and #3 is the pressure angle. You can of course find a lot of information about involute gears, but for simple illustrations it's probably easier to just try out some values and see what looks good. I've given the formula for the required distance for between two gears, it's in the example code.
    – wrtlprnft
    Jul 2, 2022 at 14:49
16

If you are not opposed to Inkscape, it will by default render gears (under the extension/render menu), and has a TikZ export extension that you can install (from here) to export TikZ code. It won't be as flexible as Caramdir's answer, but you can specify number of teeth, pitch and angle. It produces the following:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
  \begin{scope}[shift={(375.0,532.3622047)}]
    \path[draw=black] (57.0460,-5.3460) -- (59.5620,-5.5820) -- (63.4660,-4.9950) --
      (69.9930,-2.2120) -- (69.9930,2.2120) -- (63.4660,4.9950) -- (59.5620,5.5820)
      -- (57.0460,5.3460) -- (55.9060,12.5440) -- (58.3710,13.0970) --
      (61.9030,14.8620) -- (67.2510,19.5260) -- (65.8840,23.7320) --
      (58.8160,24.3620) -- (54.9220,23.7140) -- (52.6020,22.7130) --
      (49.2930,29.2060) -- (51.4670,30.4940) -- (54.2810,33.2630) --
      (57.9260,39.3520) -- (55.3260,42.9300) -- (48.4090,41.3450) --
      (44.9050,39.5250) -- (43.0090,37.8560) -- (37.8560,43.0090) --
      (39.5250,44.9050) -- (41.3450,48.4090) -- (42.9300,55.3260) --
      (39.3520,57.9260) -- (33.2630,54.2810) -- (30.4940,51.4670) --
      (29.2060,49.2930) -- (22.7130,52.6020) -- (23.7140,54.9220) --
      (24.3620,58.8160) -- (23.7320,65.8840) -- (19.5260,67.2510) --
      (14.8620,61.9030) -- (13.0970,58.3710) -- (12.5440,55.9060) --
      (5.3460,57.0460) -- (5.5820,59.5620) -- (4.9950,63.4660) -- (2.2120,69.9930)
      -- (-2.2120,69.9930) -- (-4.9950,63.4660) -- (-5.5820,59.5620) --
      (-5.3460,57.0460) -- (-12.5440,55.9060) -- (-13.0970,58.3710) --
      (-14.8620,61.9030) -- (-19.5260,67.2510) -- (-23.7320,65.8840) --
      (-24.3620,58.8160) -- (-23.7140,54.9220) -- (-22.7130,52.6020) --
      (-29.2060,49.2930) -- (-30.4940,51.4670) -- (-33.2630,54.2810) --
      (-39.3520,57.9260) -- (-42.9300,55.3260) -- (-41.3450,48.4090) --
      (-39.5250,44.9050) -- (-37.8560,43.0090) -- (-43.0090,37.8560) --
      (-44.9050,39.5250) -- (-48.4090,41.3450) -- (-55.3260,42.9300) --
      (-57.9260,39.3520) -- (-54.2810,33.2630) -- (-51.4670,30.4940) --
      (-49.2930,29.2060) -- (-52.6020,22.7130) -- (-54.9220,23.7140) --
      (-58.8160,24.3620) -- (-65.8840,23.7320) -- (-67.2510,19.5260) --
      (-61.9030,14.8620) -- (-58.3710,13.0970) -- (-55.9060,12.5440) --
      (-57.0460,5.3460) -- (-59.5620,5.5820) -- (-63.4660,4.9950) --
      (-69.9930,2.2120) -- (-69.9930,-2.2120) -- (-63.4660,-4.9950) --
      (-59.5620,-5.5820) -- (-57.0460,-5.3460) -- (-55.9060,-12.5440) --
      (-58.3710,-13.0970) -- (-61.9030,-14.8620) -- (-67.2510,-19.5260) --
      (-65.8840,-23.7320) -- (-58.8160,-24.3620) -- (-54.9220,-23.7140) --
      (-52.6020,-22.7130) -- (-49.2930,-29.2060) -- (-51.4670,-30.4940) --
      (-54.2810,-33.2630) -- (-57.9260,-39.3520) -- (-55.3260,-42.9300) --
      (-48.4090,-41.3450) -- (-44.9050,-39.5250) -- (-43.0090,-37.8560) --
      (-37.8560,-43.0090) -- (-39.5250,-44.9050) -- (-41.3450,-48.4090) --
      (-42.9300,-55.3260) -- (-39.3520,-57.9260) -- (-33.2630,-54.2810) --
      (-30.4940,-51.4670) -- (-29.2060,-49.2930) -- (-22.7130,-52.6020) --
      (-23.7140,-54.9220) -- (-24.3620,-58.8160) -- (-23.7320,-65.8840) --
      (-19.5260,-67.2510) -- (-14.8620,-61.9030) -- (-13.0970,-58.3710) --
      (-12.5440,-55.9060) -- (-5.3460,-57.0460) -- (-5.5820,-59.5620) --
      (-4.9950,-63.4660) -- (-2.2120,-69.9930) -- (2.2120,-69.9930) --
      (4.9950,-63.4660) -- (5.5820,-59.5620) -- (5.3460,-57.0460) --
      (12.5440,-55.9060) -- (13.0970,-58.3710) -- (14.8620,-61.9030) --
      (19.5260,-67.2510) -- (23.7320,-65.8840) -- (24.3620,-58.8160) --
      (23.7140,-54.9220) -- (22.7130,-52.6020) -- (29.2060,-49.2930) --
      (30.4940,-51.4670) -- (33.2630,-54.2810) -- (39.3520,-57.9260) --
      (42.9300,-55.3260) -- (41.3450,-48.4090) -- (39.5250,-44.9050) --
      (37.8560,-43.0090) -- (43.0090,-37.8560) -- (44.9050,-39.5250) --
      (48.4090,-41.3450) -- (55.3260,-42.9300) -- (57.9260,-39.3520) --
      (54.2810,-33.2630) -- (51.4670,-30.4940) -- (49.2930,-29.2060) --
      (52.6020,-22.7130) -- (54.9220,-23.7140) -- (58.8160,-24.3620) --
      (65.8840,-23.7320) -- (67.2510,-19.5260) -- (61.9030,-14.8620) --
      (58.3710,-13.0970) -- (55.9060,-12.5440) -- cycle;
  \end{scope}

\end{tikzpicture}
\end{document}

enter image description here

1
  • This is a possibility but I would have to rely on Inkscape to generate the gears for me and I wont be able to device a systematic way of generarting them like what Caramidir suggests below. I have toyed with Inkscape and I knew with the its tikzexport option I would achieve the desired results but as you can see it only defines the paths piece by piece.
    – azetina
    Jun 6, 2012 at 1:26
14

With PSTricks. This code was stolen from the given link below.

enter image description here

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

\SpecialCoor
\makeatletter
\pst@addfams{pst-gears}
\define@key[psset]{pst-gears}{Z1}{\def\psk@ZA{#1 }}
\psset[pst-gears]{Z1=20}
\define@key[psset]{pst-gears}{Z2}{\def\psk@ZB{#1 }}
\psset[pst-gears]{Z2=10}
\define@key[psset]{pst-gears}{m}{\def\psk@m{#1 }}
\psset[pst-gears]{m=0.5}
\define@key[psset]{pst-gears}{ap}{\def\psk@ap{#1 }}
\psset[pst-gears]{ap=20}
\define@key[psset]{pst-gears}{rotate}{\def\psk@rotate{#1 }}
\psset[pst-gears]{rotate=0}
\define@key[psset]{pst-gears}{color1}{\pst@getcolor{#1}\pscolora}
\psset[pst-gears]{color1={[rgb]{0.625 0.75 1}}}
\define@key[psset]{pst-gears}{color2}{\pst@getcolor{#1}\pscolorb}
\psset[pst-gears]{color2={[rgb]{0.75 1 0.75}}}
%
\def\pstgears{\pst@object{pstgears}}
\def\pstgears@i{{%
\pst@killglue
\begin@SpecialObj
\addto@pscode{%
/Z1 \psk@ZA def
/m1 \psk@m def
/Z2 \psk@ZB def
/m2 \psk@m def
/ap \psk@ap def
/color1 {\pst@usecolor\pscolora } def
/color2 {\pst@usecolor\pscolorb } def
/linecolor  {\pst@usecolor\pslinecolor} def
/cm {\pst@number\psunit mul } bind def
/Pi 3.14159265359 def
/rad2deg { 180 mul Pi div } bind def
/deg2rad { 180 div Pi mul } bind def
/Datas {
         /Z@ exch def
         /m@ exch def
         /R@ {m@ Z@ mul 2 div } bind def % cercle primitif
         /Rb {R@ ap cos mul } bind def % cercle de base
         /Rp {R@ 2 mul 2.5 m@ mul sub 2 div } bind def % cercle de pied
         /Rt {R@ 2 mul 2 m@ mul add 2 div } bind def % cercle de tête
         % les valeurs suivantes sont en radians
         /ThetaP {R@ Rb div dup mul 1 sub sqrt } bind def % intersection avec cercle primitif
         /ThetaT {Rt Rb div dup mul 1 sub sqrt } bind def % intersection avec cercle de tete
         % Les valeurs suivantes ont en degrés
         /ThetaTdeg {Rt Rb div dup mul 1 sub sqrt rad2deg } bind def %
         /ThetaPdeg {R@ Rb div dup mul 1 sub sqrt rad2deg } bind def
         /DeltaP {ThetaPdeg sin ThetaP ThetaPdeg cos mul sub
                  ThetaPdeg cos ThetaP ThetaPdeg sin mul add
                  atan } bind def
         /DeltaT {ThetaTdeg sin ThetaT ThetaTdeg cos mul sub
                  ThetaTdeg cos ThetaT ThetaTdeg sin mul add
                  atan } bind def
         /DeltaS {Pi 2 div Z@ div } bind def
         /DeltaSdeg {90 Z@ div } bind def
         /AngleDent {360 Z@ div} bind def
         /Alpha {DeltaSdeg DeltaP add DeltaT sub } bind def
         /2Beta {DeltaSdeg DeltaP add 2 mul } bind def
         /Beta_  {DeltaSdeg DeltaP add neg} bind def
         /ptA {Rp cm 0} bind def
         /ptB {Rb cm 0} bind def
         /ptC {Rp cm DeltaSdeg 2 mul neg 2Beta 2 div add cos mul
               Rp cm DeltaSdeg 2 mul neg 2Beta 2 div add sin mul} bind def
         /ptA'{Rp cm DeltaP DeltaSdeg add 2 mul cos mul
               Rp cm DeltaP DeltaSdeg add 2 mul sin mul} bind def
         /ptB'{Rb cm DeltaP DeltaSdeg add 2 mul cos mul
               Rb cm DeltaP DeltaSdeg add 2 mul sin mul} bind def
         /ptC'{Rp cm DeltaSdeg 3 mul DeltaP add cos mul
               Rp cm DeltaSdeg 3 mul DeltaP add sin mul} bind def
         /Raxe {Rp 4 div } bind def
         /A@0 14.5 def
         /Rarct {Rp 2 mul Pi mul Z@ div 8 div cm} bind def
         }
         def
% Le symetrique P' de P par rapport a la l'axe de la dent
% Delta(axe de la dent) y=x*tan(Beta)
% x'=y*sin(2*Beta)+x*cos(2*Beta)
% y'=x*sin(2*Beta)-y*cos(2*Beta)
% x y symAxe -> x' y'
/symAxe {
 2 dict begin
  /y exch def
  /x exch def
  y 2Beta sin mul x 2Beta cos mul add % x'
  x 2Beta sin mul y 2Beta cos mul sub % y'
 end
 }
 def
 %
% Rotation pour amener l'axe de la dent horizontal
%
/RotDent {
 2 dict begin
/y exch def
/x exch def
 i@ cos x mul i@ sin y mul sub
 i@ sin x mul i@ cos y mul add
end
} def
%
% developpante du cercle de base
%
 /devCercle {
  1 dict begin
  /t exch def % en degres
  Rb t cos t deg2rad t sin mul add mul cm % x
  Rb t sin t deg2rad t cos mul sub mul cm % y
 end
 }
 def
%%%% definition de la roue dentee %%%%%%
/Roue {
% Datas
% arc de développante
/tabArcDev [
0 1 ThetaTdeg { /i@ exch def
 [i@ devCercle] } for
 ] def
%
/n@ tabArcDev length def
%
/tabDent [
% l'arc de developpante initial
  tabArcDev aload pop
% l'arc ce cercle de tete
DeltaT 0.1 2Beta DeltaT sub {/i@ exch def
 [Rt cm i@ cos mul
  Rt cm i@ sin mul]
 } for
% le symetrique de l'arc de developpante par rapport a l'axe de la dent
n@ 1 sub -1 0  {
    /compteur exch def
    [tabArcDev compteur get aload pop symAxe]
    } for
    ] def
% tracé de la dent
/n2@ tabDent length def
newpath
ptC moveto
0 1 Z@ 1 sub {/i@ exch AngleDent mul def
ptA RotDent ptB RotDent Rarct arct
ptB RotDent lineto
0 1 n2@ 1 sub {
    /compteur exch def
    tabDent compteur get aload pop
    RotDent lineto } for
ptA' RotDent ptC' RotDent Rarct arct
ptC' RotDent lineto
} for
} def
%%%% fin de la definition de la roue dentee %%%
%%% axe de la roue %%%
/AXE {
%newpath
 Raxe 4 div cm
 A@0 cos Raxe mul cm moveto
 0 0 Raxe cm 90 A@0 sub 90 A@0 add arcn
 Raxe 4 div cm neg
 A@0 cos Raxe mul cm
 lineto
 Raxe 4 div cm neg
 Raxe A@0 cos 0.25 add mul cm
 lineto
 Raxe 4 div cm
 Raxe A@0 cos 0.25 add mul cm
 lineto
} def
%%% clavette %%%
/CLAVETTE {
newpath
 Raxe 4 div cm
 A@0 cos 0.25 sub Raxe mul cm moveto
 Raxe 4 div cm
 Raxe A@0 cos 0.25 add mul cm lineto
 Raxe 4 div cm neg
 Raxe A@0 cos 0.25 add mul cm lineto
 Raxe 4 div cm neg
 A@0 cos 0.25 sub Raxe mul cm lineto
closepath
} def
%%% Les dessins de l'engrenage %%%%%%
%%%%%%%%%% Roue N°1 %%%%%%%%%%%%%%%%%
/AngleRotation \psk@rotate def
gsave
0 0 translate
m1 Z1 Datas
Beta_ AngleRotation sub rotate
Roue
AXE
closepath
color1
fill
%m1 Z1
Roue
closepath
linecolor
stroke
AXE
closepath
0.8 setgray
fill
AXE
closepath
linecolor
stroke
CLAVETTE
0 0.125 0.25 0.25 setcmykcolor
fill
CLAVETTE
linecolor
stroke
grestore
%%%%%%%%%% Roue N°2 %%%%%%%%%%%%%%%%%
gsave
m2 Z1 Z2 add mul 2 div cm 0 translate
m2 Z2 Datas
DeltaSdeg DeltaP add neg 180 Z2 div add 180 sub Z1 Z2 div AngleRotation mul add rotate
%m2 Z2
Roue
AXE
closepath
color2
fill
%m2 Z2
Roue
closepath
linecolor
stroke
AXE
closepath
0.8 setgray
fill
AXE
closepath
linecolor
stroke
CLAVETTE
0 0.125 0.25 0.25 setcmykcolor
fill
CLAVETTE
linecolor
stroke
grestore
}
\end@SpecialObj
 }}%
\makeatother
\usepackage{multido}
\begin{document}
%\multido{\i=0+30}{12}
{%
\begin{pspicture}[showgrid](-4,-4)(7,4)
\pstgears[Z1=24,Z2=12,m=0.25,rotate=-12,linewidth=0.025]
\end{pspicture}}

\end{document} 

Animated version:

For the animated version see this blog.

1
4

I have adapted rpapa's answer. I have added one more gear and arrows indicating the gear movement direction. Besides I have made changes in order to have a gear core.

enter image description here

\documentclass[tikz,margin=10pt]{standalone}
\usetikzlibrary{arrows}

\tikzset{pics/gear/.style n args={3}{
code={
    \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}

    \path[pic actions] foreach \zz in{1,...,\Zb}{
        \ifnum\zz=1
            % don't use a lineto in the first iteration
            (\zz/\Zb*360-\Angledecal:\Rp)
        \else
            -- (\zz/\Zb*360-\Angledecal:\Rp)
        \fi
        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)})
    } -- cycle;
}
}}

\begin{document}
\begin{tikzpicture}
    % observations:
    %
    %  - param #1 and #3 must be equal for gears to mesh
    %  - the required distance is (#2_1 + #2_2) * #1 / 2
    %  - for odd numbers of teeth, gears on a horizontal axis fit without rotation

    \pic[draw,fill=gray!80]        at (0,0)   {gear={0.50}{17}{15}};
    \pic[draw,fill=magenta!60]     at (6,0)   {gear={0.50}{7}{15}};
    \pic[draw,fill=blue!40!,rotate=36]  at (8.7,-2.9) {gear={0.5}{9}{15}};
    \foreach \p in {(0,0),(6,0),(8.7,-2.9)} \fill [fill=white]\p circle(0.5cm); 
    \draw[->,>=stealth',thick, line width=0.5mm,color=white]  (-1,2) arc[radius=2, start angle=120, end angle=0];
    \draw[->,>=stealth', line width=0.5mm,color=white]  (6.5,0.6) arc[radius=0.75, start angle=40, end angle=200];
    \draw[->,>=stealth',thick, line width=0.5mm,color=white]  (8,-2) arc[radius=1.25, start angle=120, end angle=0];

\end{tikzpicture}

\end{document}
1

I adapted the answer of Alain Matthes. The first thing is that teeth is already plural. The next thing is that I found some glitches in the peaks of the teeth (I use very small teeth). To avoid them, I choose to simply use line segments instead of arcs.

The last thing is that I only wish to specify two things, namely the number of teeth, and the offset in teeth, because all my gears will be in the same style. The offset is needed to make the gears fit into each other. I only needed to choose offsets 0 and 0.5 in my application.

% #1 number of teeth
% #2 offset in teeth
\newcommand{\gear}[2]{%
  (#2/#1*360:#1/20+0.1) -- (#2/#1*360+180/#1:#1/20-0.2)
  \foreach \i [evaluate=\i as \n using \i-1+#2] in {2,...,#1} {%
  -- (\n/#1*360:#1/20+0.1) -- (\n/#1*360+180/#1:#1/20-0.2)
  }
  -- cycle
}

The alignment radius of the gear (in cm) is computed as 1/20 times the number of teeth. The inner radius is 2 mm less and the outer radius is 1 mm more. You do not want to specify those by hand all the time.

The macro yields a closed path of line segments, which can be tweaked on the application level. e.g. rounding and making holes.

EDIT: if you draw with option rounded corners=2mm, combined with an inner radius of 3 mm less and an outer radius of 2 mm more instead of 2 mm and 1 mm respectively, you get better looking gears. You need to stretch things up, so apparently, the rounded corners option eats from the points as a sander.

You must log in to answer this question.

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