como desenhar uma corrente de engrenagens

como desenhar uma corrente de engrenagens

Eu gostaria de desenhar uma corrente de engrenagens, assim: insira a descrição da imagem aqui

Estou usando a macro fornecida por Alain Matthes emCriando engrenagens no TikZpara desenhar uma única engrenagem com algumas modificações para obter o efeito de "engrenagem dupla" (ou seja, uma engrenagem interna/externa).

Meu código real é 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 produz:insira a descrição da imagem aqui

para mover a segunda marcha para a esquerda/direita coloquei as engrenagens em a \matrixde modo que só preciso copiar o código da primeira marcha na segunda célula da matriz e especificar a column sepde forma que as engrenagens fiquem na distância desejada. Este método, entretanto, não funciona mais quando você adiciona uma terceira marcha que precisa de uma marcha diferente column sep.

mover a segunda marcha para cima/para baixo para obter o efeito da primeira imagem que tentei xshifte yshiftopções \draw(foi assim que consegui a primeira imagem) mas dá muito trabalho e requer muitas recompilações.

Então minha pergunta é:
Existe uma maneira melhor de mover uma engrenagem (onde uma engrenagem consiste em dois \drawe dois \nodecomandos, como mostrado no código) para a esquerda-direita-cima-baixo em relação à outra sem ter que posicionar manualmente isso com xshifte yshift?

Uma abordagem mais geral

Para tornar a questão mais geral, vamos considerar apenas o caso em que cada engrenagem é feita apenas por uma engrenagem, sem a engrenagem interna, fundo, etc., o que tikzpictureno código acima se torna:

\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}

insira a descrição da imagem aqui
Como encadear duas ou mais marchas mudando de posição como na primeira imagem?

Responder1

Aqui está um ponto de partida e apenas uma das muitas ideias de comoentradaos dados.

O next gearestilo toma seus argumentos na forma de

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

onde

  • :<text>e
  • [<opt>:<text>]são opcionais,
  • <abs angle>denota o ângulo/direção absoluto da próxima marcha e
  • <next gear’s radius>especifica o raio da próxima engrenagem.

A turtlebiblioteca é usada apenas para seu forwardestilo e \tikz@lib@turtle@dirmacro. Para ser honesto, isso poderia ter sido codificado sem a biblioteca, mas tudo bem…

Atualizar

Bem, ouça um novo equipamento ( \ngear[<options>](<point>)) e experimente uma saída.

A combinação de engrenagens envolve um pouco de matemática, pois o número de dentes, a largura desses dentes e a rotação dependem da engrenagem anterior e de sua rotação.

Você pode sequestrar \qrr@tikz@do@nextgear@e inserir os cálculos necessários para a próxima marcha por conta própria.

(Você pode até redefinir \ngearpara atuar como front-end para uma das \gearmacros já definidas no 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}

Saída

insira a descrição da imagem aqui

informação relacionada