cómo dibujar una cadena de engranajes

cómo dibujar una cadena de engranajes

Me gustaría dibujar una cadena de engranajes, como esta: ingrese la descripción de la imagen aquí

Estoy usando la macro proporcionada por Alain Matthes enCreando engranajes en TikZpara dibujar un solo engranaje con alguna modificación para obtener el efecto de "doble engranaje" (es decir, un engranaje interior/exterior).

Mi código real es este:

\documentclass{standalone}
\usepackage{tikz}

\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}
    \matrix[column sep=-0.1cm,draw=none,fill=none,ampersand replacement=\&] {
    %%%%%%%%%%%%%%
    % First gear %
    %%%%%%%%%%%%%%
    \node[circle,minimum size=40mm,fill=gray,shade] at (0,0){};
    \node[circle,minimum size=30mm,fill=white] at (0,0){};
    \draw[thick,rotate=10,fill=gray,shade] \gear{18}{2}{2.2}{10}{2};
    \draw[thick,rotate=22,fill=white] \gear{18}{1.5}{1.7}{6}{1};\&
    %%%%%%%%%%%%%%%
    % Second gear %
    %%%%%%%%%%%%%%%
    \node[circle,minimum size=40mm,fill=gray,shade] at (0,0){};
    \node[circle,minimum size=30mm,fill=white] at (0,0){};
    \draw[thick,rotate=10,fill=gray,shade] \gear{18}{2}{2.2}{10}{2};
    \draw[thick,rotate=22,fill=white] \gear{18}{1.5}{1.7}{6}{1};\\
    };
    \end{tikzpicture}
  \end{document}

que produce:ingrese la descripción de la imagen aquí

Para mover la segunda marcha hacia la izquierda/derecha, puse los engranajes en una \matrixde modo que solo necesito copiar el código de la primera marcha en la segunda celda de la matriz y especificar una column septal que las marchas estén a la distancia deseada. Sin embargo, este método ya no funciona cuando agregas una tercera marcha que necesita una velocidad diferente column sep.

para mover la segunda marcha hacia arriba/abajo para obtener el efecto de la primera imagen que probé xshifty yshiftlas opciones \draw(así es como obtuve la primera imagen) pero es mucho trabajo y requiere muchas recompilaciones.

Entonces mi pregunta es:
¿Existe una mejor manera de mover un engranaje (donde un engranaje consta de dos \drawy dos \nodecomandos, como se muestra en el código) hacia la izquierda, derecha, arriba y abajo con respecto al otro sin tener que posicionarlo manualmente? ¿Con xshifty yshift?

Un enfoque más general

Para hacer la pregunta más general, consideremos el caso en el que cada engranaje está formado por un solo engranaje, sin el engranaje interno, el fondo, etc., lo que tikzpictureen el código anterior se convierte en:

\begin{tikzpicture}
    \matrix[column sep=-0.1cm,draw=none,fill=none,ampersand replacement=\&] {
    %%%%%%%%%%%%%%
    % First gear %
    %%%%%%%%%%%%%%
    \draw[thick] \gear{18}{2}{2.2}{10}{2};\&
    %%%%%%%%%%%%%%%
    % Second gear %
    %%%%%%%%%%%%%%%
    \draw[thick] \gear{18}{2}{2.2}{10}{2};\\
    };
  \end{tikzpicture}

ingrese la descripción de la imagen aquí
¿Cómo encadenar dos o más marchas cambiando su posición como en la primera imagen?

Respuesta1

Éste es un punto de partida y sólo una de muchas ideas sobre cómoaportelos datos.

El next gearestilo toma sus argumentos en forma de

[<opt>:<text>]<abs angle>:<next gear’s radius>

dónde

  • :<text>y
  • [<opt>:<text>]son opcionales,
  • <abs angle>denota el ángulo/dirección absolutos de la siguiente marcha y
  • <next gear’s radius>Especifica el radio de la siguiente marcha.

La turtlebiblioteca sólo se utiliza por su forwardestilo y la \tikz@lib@turtle@dirmacro. Para ser honesto, esto podría haberse codificado sin la biblioteca, pero bueno...

Actualizar

Bueno, escuchemos una nueva marcha ( \ngear[<options>](<point>)) y una prueba de salida.

La combinación de engranajes implica un poco de matemática ya que el número de dientes, el ancho de estos dientes y la rotación dependen del engranaje anterior y su rotación.

Puedes secuestrar \qrr@tikz@do@nextgear@e insertar los cálculos necesarios para la siguiente marcha por tu cuenta.

(Incluso puede redefinirlo \ngearpara que actúe como interfaz de una de las \gearmacros ya definidas en TeX.sx).

Código

\documentclass[tikz,convert=false]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,turtle}
\makeatletter
\newcommand*{\gearset}{\pgfqkeys{/gear}}
\newcommand*{\geargetvalue}[1]{\pgfkeysgetvalue{/gear/#1}}
\gearset{
    outer radius/.initial=1cm,
    outer height/.initial=5cm,
    outer width/.initial=.5cm,
    outer number/.initial=10,
    outer rotate/.initial=0,
    inner radius/.initial=,
    inner rotate/.initial=0,
    inner height/.initial=.2cm,
    inner width/.initial=.2cm,
    inner number/.initial=18,
    height/.style={/gear/outer height={#1},/gear/inner height={#1}},
    width/.style={outer width={#1},inner width={#1}},
%   outer outer radius=.4pt, rounded corners?
%   inner outer radius=.2pt,
%   outer inner radius=.4pt,
%   inner inner radius=.2pt,
    /tikz/every gear/.style={draw,fill=none,even odd rule,rounded corners=.5pt},
%   /tikz/every outer gear/.style={top color=blue, bottom color=green},
%   /tikz/every inner gear/.style={draw=blue,fill=white},
}
\newcommand*{\ngear}[1][]{\begingroup\gearset{#1}\ngear@}
\def\ngear@(#1){%
    \geargetvalue{outer radius}\qrr@gear@outerR
    \geargetvalue{inner radius}\qrr@gear@innerR
    \geargetvalue{outer number}\qrr@gear@outerN
    \geargetvalue{inner number}\qrr@gear@innerN
    \geargetvalue{outer height}\qrr@gear@outerH
    \geargetvalue{inner height}\qrr@gear@innerH
    \geargetvalue{outer width}\qrr@gear@outerW
    \geargetvalue{inner width}\qrr@gear@innerW
    \geargetvalue{outer rotate}\qrr@gear@outerRot
    \geargetvalue{inner rotate}\qrr@gear@innerRot
    \pgfmathsetmacro\qrr@gear@ooArc{(\qrr@gear@outerW)/(\qrr@gear@outerR+\qrr@gear@outerH)/pi*180}%
    \pgfmathsetmacro\qrr@gear@ioArc{180/(\qrr@gear@outerN) - \qrr@gear@ooArc}%
    \pgfmathsetmacro\qrr@gear@oiArc{(\qrr@gear@innerW)/(\qrr@gear@innerR+\qrr@gear@innerH)/pi*180}%
    \pgfmathsetmacro\qrr@gear@iiArc{180/(\qrr@gear@innerN) - \qrr@gear@oiArc}%
    \pgfmathtruncatemacro\qrr@gear@outerN{\qrr@gear@outerN-1}%
    \pgfmathtruncatemacro\qrr@gear@innerN{\qrr@gear@innerN-1}%
    \scope[shift={(#1)}]%
    \path[every gear/.try, every outer gear/.try] ({\qrr@gear@outerRot}:{\qrr@gear@outerR+\qrr@gear@outerH})
        \foreach \@tooth in {0,...,\qrr@gear@outerN} {
            \pgfextra
                \pgfmathsetmacro\qrr@gear@sa{\qrr@gear@outerRot+2*\@tooth*(\qrr@gear@ooArc+\qrr@gear@ioArc)}%
            \endpgfextra
            arc[radius={\qrr@gear@outerR+\qrr@gear@outerH}, start angle=\qrr@gear@sa, delta angle=\qrr@gear@ooArc]
            -- (\qrr@gear@sa+\qrr@gear@ooArc:{\qrr@gear@outerR})
            arc[radius={\qrr@gear@outerR}, start angle=\qrr@gear@sa+\qrr@gear@ooArc, delta angle=2*\qrr@gear@ioArc]
            -- (\qrr@gear@sa+\qrr@gear@ooArc+2*\qrr@gear@ioArc:{\qrr@gear@outerR+\qrr@gear@outerH})
            arc[radius={\qrr@gear@outerR+\qrr@gear@outerH}, start angle=\qrr@gear@sa+\qrr@gear@ooArc+2*\qrr@gear@ioArc, delta angle=\qrr@gear@ooArc]
        }
        \ifx\qrr@gear@innerR\pgfutil@empty\else
%       ; % un-comment this and the next line to have two paths
%   \path[every gear/.try, every inner gear]
    (0:{\qrr@gear@innerR-\qrr@gear@innerH})
    \foreach \@tooth in {0,...,\qrr@gear@innerN} {
        \pgfextra
            \pgfmathsetmacro\qrr@gear@sa{\qrr@gear@innerRot+2*\@tooth*(\qrr@gear@oiArc+\qrr@gear@iiArc)}%
        \endpgfextra
        arc[radius={\qrr@gear@innerR-\qrr@gear@innerH}, start angle=\qrr@gear@sa, delta angle=\qrr@gear@oiArc]
        -- (\qrr@gear@sa+\qrr@gear@oiArc:{\qrr@gear@innerR})
        arc[radius={\qrr@gear@innerR}, start angle=\qrr@gear@sa+\qrr@gear@oiArc, delta angle=2*\qrr@gear@iiArc]
        -- (\qrr@gear@sa+\qrr@gear@oiArc+2*\qrr@gear@iiArc:{\qrr@gear@innerR-\qrr@gear@innerH})
        arc[radius={\qrr@gear@innerR-\qrr@gear@innerH}, start angle=\qrr@gear@sa+\qrr@gear@oiArc+2*\qrr@gear@iiArc, delta angle=\qrr@gear@oiArc]
    }
    \fi
    ;
    \endscope
    \endgroup
}
\def\qrr@tikz@gear@current@radius{0pt}
\def\qrr@tikz@do@nextgear{\pgfutil@ifnextchar[\qrr@tikz@do@nextgear@{\qrr@tikz@do@nextgear@[]}}
\def\qrr@tikz@do@nextgear@[#1]#2:#3\@qrr@tikz@do@nextgear{%
    \pgfmathsetmacro\qrr@tikz@gear@distance{\qrr@tikz@gear@current@radius+(#3)+\pgfkeysvalueof{/gear/outer height}}%
    \pgfmathsetmacro\qrr@tikz@gear@current@radius{abs(#3)}%
    \gdef\tikz@lib@turtle@dir{#2}%
    \pgfkeysalso{/tikz/turtle/forward/.expanded=\qrr@tikz@gear@distance pt}
    \pgfgetlastxy\pgf@gear@@x\pgf@gear@@y
    \pgfkeysalso{/tikz/gear={#1, outer radius=\qrr@tikz@gear@current@radius pt}{\pgf@gear@@x,\pgf@gear@@y}}
}
\tikzset{
    gear/.style 2 args={/tikz/insert path={\pgfextra{\ngear[#1](#2)}}},
    turtle/next gear/.code=\qrr@tikz@do@nextgear#1\@qrr@tikz@do@nextgear
}

\begin{document}
\begin{tikzpicture}[show background grid,/gear/height=.3cm,every gear/.append style=thick]
    \draw[dash pattern={on \pgflinewidth off 2\pgflinewidth},thin] (0,0) [turtle={
        next gear/.list={
            0:2cm,
            {[outer rotate=-90,outer width=.18cm,outer number=10]90:2cm},
            {[outer width=.49cm,outer number=14,outer rotate=0]30:3cm},
            {[outer width=.2cm,outer rotate=18]120:2cm}
        }}];
\end{tikzpicture}
\end{document}

Producción

ingrese la descripción de la imagen aquí

información relacionada