
Me gustaría dibujar una cadena de engranajes, como esta:
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:
Para mover la segunda marcha hacia la izquierda/derecha, puse los engranajes en una \matrix
de modo que solo necesito copiar el código de la primera marcha en la segunda celda de la matriz y especificar una column sep
tal 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é xshift
y yshift
las 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 \draw
y dos \node
comandos, como se muestra en el código) hacia la izquierda, derecha, arriba y abajo con respecto al otro sin tener que posicionarlo manualmente? ¿Con xshift
y 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 tikzpicture
en 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}
¿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 gear
estilo 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 turtle
biblioteca sólo se utiliza por su forward
estilo y la \tikz@lib@turtle@dir
macro. 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 \ngear
para que actúe como interfaz de una de las \gear
macros 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}