
Ich möchte eine Zahnradkette zeichnen, etwa so:
Ich verwende das Makro von Alain Matthes inZahnräder in TikZ erstellenzum Zeichnen eines einzelnen Zahnrads mit einigen Modifikationen, um den „Doppelzahnrad“-Effekt zu erzielen (d. h. ein Innen-/Außenzahnrad).
Mein eigentlicher Code ist dieser:
\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}
was ergibt:
Um das zweite Zahnrad nach links/rechts zu bewegen, habe ich die Zahnräder in ein gesetzt, \matrix
sodass ich nur den Code vom ersten Zahnrad in die zweite Zelle der Matrix kopieren und ein angeben muss, column sep
sodass die Zahnräder den gewünschten Abstand haben. Diese Methode funktioniert jedoch nicht mehr, wenn Sie ein drittes Zahnrad hinzufügen, das ein anderes benötigt column sep
.
um den zweiten Gang hoch-/runterzubewegen und so den Effekt des ersten Bildes zu erzielen, habe ich es mit xshift
und yshift
Optionen versucht \draw
(so habe ich das erste Bild erhalten), aber es ist viel Arbeit und erfordert viele Neukompilierungen.
Meine Frage lautet also:
Gibt es eine bessere Möglichkeit, ein Zahnrad (wobei ein Zahnrad aus zwei \draw
und zwei Befehlen besteht, wie im Code gezeigt) in Bezug auf das andere nach links-rechts-oben-unten zu bewegen, ohne es manuell mit und \node
positionieren zu müssen ?xshift
yshift
Ein allgemeinerer Ansatz
Um die Frage allgemeiner zu formulieren, betrachten wir einfach den Fall, bei dem jedes Zahnrad nur aus einem Zahnrad besteht, ohne das innere Zahnrad, den Hintergrund usw. tikzpicture
Im obigen Code ergibt sich daraus:
\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}
Wie verkettet man zwei oder mehr Zahnräder, die ihre Position verändern, wie im ersten Bild?
Antwort1
Dies ist ein Ausgangspunkt und nur eine von vielen Ideen, wie SieEingangdie Daten.
Der next gear
Stil argumentiert in Form von
[<opt>:<text>]<abs angle>:<next gear’s radius>
Wo
:<text>
Und[<opt>:<text>]
sind fakultativ,<abs angle>
bezeichnet den absoluten Winkel/die absolute Richtung des nächsten Gangs und<next gear’s radius>
Gibt den Radius des nächsten Zahnrads an.
Die turtle
Bibliothek wird nur für ihren forward
Stil und das \tikz@lib@turtle@dir
Makro verwendet. Ehrlich gesagt hätte man das Ganze auch ohne die Bibliothek codieren können, aber na ja …
Aktualisieren
Also, hier ist ein neuer Gang ( \ngear[<options>](<point>)
) und ein Versuch einer Ausgabe.
Die Kombination der Zahnräder erfordert ein wenig Mathematik, da die Anzahl der Zähne, die Breite dieser Zähne und die Drehung vom vorherigen Zahnrad und seiner Drehung abhängen.
Sie können die \qrr@tikz@do@nextgear@
erforderlichen Berechnungen für den nächsten Gang selbst übernehmen und einfügen.
(Sie können es sogar neu definieren, \ngear
damit es als Front-End für eines der bereits definierten \gear
Makros in TeX.sx fungiert.)
Code
\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}