0

enter image description hereI want to draw a mechanical wagoon for a physics book with a parameterized approach. These should be the parameters:

#0 name, the name of the object, e.g. mywagon

#1 position of the wagon as coordinate, center below at the height of the ground e.g. (4.5,0)

#2 (optional) width of the mass, e.g. 5, default value 3

#3 (optional) height of the mass, e.g. 4, default 2/3*width

#4 (optional) wheel: the diameter of the wheel, default 1/5*width

#5 (optional) gap: the gap between edge of mass and wheel, default 1/10*wheel

#6 (optional) overlap: The overlap of mass and wheel, default 1/3*wheel

The call in tikz should then look something like this:

\begin{tikzpicture}
   \draw[ground] (0,0) -- (9,0);%ground
   \wagoon[name=mywagon, width=5, height=4.2, wheel=1.1, gap=0.6, overlap=0.4] at (4.5,0);
   \draw[rope] mywagon-mass.east -- ++(1,0);
   \draw[rope] mywagon-mass.west -- ++(-1,0);
   \draw[arrow] mywagon-wheel-2.center -- ++(2,0);
   \draw[ground] (0,-6) -- (9,-6);%ground
   \wagon[name=mywagon2, width=5, very thick, red] at (4.5,-6);%with defaults of other optional parameters and then additional very thick and red
\end{tikzpicture}

The wagoon should consist out of normal nodes: Ohne rectangle and two circles

In the further course of use, it should be possible to access the anchors in the drawing via the object.anchor notation. This is important, for example to attach ropes to the wagoon afterwards.

The names of the sub-nodes inside should be:

<name>-mass for the mass, e.g. mywagon-mass

<name>-wheel-1 and <name>-wheel-2 for the wheels, e.g. mywagon-wheel-1 and mywagon-wheel-2

where <name> is the value of parameter #0 named name

Of course, I could make a non-parameterized drawing of this wagon, but I don't think that's helpful here, but rather annoying, because then you might adopt wrong approaches from me in the structure of the drawing.

It is important that the tikz code for the wagon is stored in the preamble so that the code is also available in other drawings.

\documentclass[border=10pt]{standalone}%
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzset{
  mass/.style={rectangle, draw, thick, fill=gray!25},%
  wheel/.style={circle, draw, thick, fill=white}},%
  wheelaxle/.style={circle, draw, fill}},%
  rope/.style={blue, thick},%
  ground/.style={thick},%
  arrow/.style={-latex, thick},%
}
% global tikz-code here

\begin{document}
\begin{tikzpicture}
   \draw[ground] (0,0) -- (9,0);%ground
   %\wagoon[name=mywagon, width=5, height=4.2, wheel=1.1, gap=0.6, overlap=0.4] at (4.5,0);
   \draw[rope] mywagon-mass.east -- ++(1,0);
   \draw[rope] mywagon-mass.west -- ++(-1,0);
   \draw[arrow] mywagon-wheel-2.center -- ++(2,0);
   \draw[ground] (0,-6) -- (9,-6);%ground
   %\wagoon[name=mywagon2, width=5, very thick, red] at (4.5,-6);%with defaults of other optional parameters and then additional very thick and red
\end{tikzpicture}
\end{document}
4
  • So you put a specification (a drawing request?) and the relevant tags ... but what is your question? Please clarify
    – MS-SPO
    May 27 at 12:45
  • Of course I understand your point. The question is implicit in the assignment. But I bet you know that. I've found a lot of mechanical wagoons on the web but none of them are really universally adaptable or work with anchors. There are nice one-offs, but I need a universally adaptable template. I think the situation in the field of mechanics is something like finding many lovingly designed electrotechnical circuits on the web, but no tool like CircuiTikz is available.
    – Michael.H
    May 27 at 20:00
  • 1
    You recognized it: I can describe exactly what I want, but I don't see myself in a position to realize such things with my modest knowledge. When I see the many beautiful individual solutions that painstakingly draw each wagoon again and again, I believe that my request is very useful because it solves the problem in the long term.
    – Michael.H
    May 27 at 20:01
  • Thanks. // Suggestion: put these kind of extra infos into the question next time, so it's easier to find, later. // The problem is: code is the "currency" in this place, so your question was at risk of being closed (potential do-it-for-me request). // Learn from John, see, how close you were. Look up commands in the manual in parallel. Next, learn to fly from Qrrbrbirlbel, below. // Happy drawing :)
    – MS-SPO
    May 27 at 20:28

2 Answers 2

6

Since you're working with nodes, it is much easier to use lengths instead of unitless values which is what I'm using here.

If you want an interface where you just input the ratios in relation to the waggon width or the wheel diameter … that's also possible.

The implementation of \tikzwaggon requires a [] argument and does not allow a at (coordinate) or (name) after the ].

The following nodes are defined inside the pic waggon:

  • (<name>-mass) (rectangle),
  • (<name>-left wheel) (circle),
  • (<name>-right wheel) (circle),
  • (<name>-left axle) (circle),
  • (<name>-right axle) (circle),
  • (<name>-left rope) (coordinate) and
  • (<name>-right rope) (coordinate)

where <name> is the name of the pic.

Code

\documentclass[tikz]{standalone}
\tikzset{
  waggon width/.initial   = 3cm,
  waggon height/.initial  = .6667*(\pgfkeysvalueof{/tikz/waggon width}),
  waggon wheel diameter/.initial = .2*(\pgfkeysvalueof{/tikz/waggon width}),
  waggon gap/.initial     = .1   *(\pgfkeysvalueof{/tikz/waggon wheel diameter}),
  waggon overlap/.initial = .3333*(\pgfkeysvalueof{/tikz/waggon wheel diameter}),
  waggon rope length/.initial    = 1cm,
  waggon axle diameter/.initial  = +1pt,
  waggon/rope/.style=line to,
  waggon/axle/.style={
    fill, shape=circle, inner sep=+0pt, outer sep=auto,
    name=-#1 axle, minimum size=\pgfkeysvalueof{/tikz/waggon axle diameter}},
  waggon/mass/.style={
    draw, shape=rectangle, inner sep=+0pt, outer sep=auto,
    minimum width=\pgfkeysvalueof{/tikz/waggon width},
    minimum height=\pgfkeysvalueof{/tikz/waggon height},
    at=(up:{\pgfkeysvalueof{/tikz/waggon wheel diameter}
          -(\pgfkeysvalueof{/tikz/waggon overlap})}),
    anchor=south, name=-mass, node contents=},
  waggon/wheel/.style={
    draw, shape=circle, inner sep=+0pt, outer sep=auto,
    minimum size=\pgfkeysvalueof{/tikz/waggon wheel diameter},
    at=(#1:{.5*(\pgfkeysvalueof{/tikz/waggon width})
               -\pgfkeysvalueof{/tikz/waggon gap}
           -.5*(\pgfkeysvalueof{/tikz/waggon wheel diameter})}),
    anchor=south, name=-#1 wheel, label={[waggon/axle=#1]center:},
    node contents=},
  waggon/.pic={
    \tikzset{transform shape}
    \node[waggon/mass];
    \foreach\t in{left, right} \node[waggon/wheel=\t];
    \foreach\t/\tt in{west/left, east/right}
    \draw[waggon/rope=\tt] (-mass.\t)
      to +(\t:{\pgfkeysvalueof{/tikz/waggon rope length}})
      coordinate (-\tt\space rope);},
    @waggon/.style={
      pic type=waggon,
      height/.style={waggon height={##1}},
      width/.style={waggon width={##1}},
      wheel/.style={waggon wheel diameter={##1}},
      gap/.style={waggon gap={##1}},
      overlap/.style={waggon overlap={##1}},
      axle/.style={waggon axle diameter={##1}}},
}
\def\tikzwaggon#1[{\pic#1[@waggon,}
\begin{document}
\tikz[sloped, column sep=5mm]
  \matrix{
    \draw (0,0) -- pic(s){waggon} (right:5);
    \draw[green, ->] (s-left axle) -- +(right:1cm);
    &
    \draw (0,0) -- pic[waggon width       = 2cm,
                       waggon height      = 1cm,
                       waggon gap         = 3mm,
                       waggon rope length = 5mm,
                       waggon/rope/.style={loop ####1},
                       waggon/mass/.append style={
                         rounded corners=5mm,
                         fill=red!50!orange,
                         label={center:\tiny Wurst on Wheels}},
                       waggon/wheel/.append style={fill=blue!50}]{waggon} (60:5);
  \\};

\begin{tikzpicture}
\tikzwaggon (s) at (4.5, 0) [gray!50, line width=2mm, axle=5pt];
\foreach \anchor/\placement in {
     -mass.west/above, -left rope/below left,
     -mass.east/above, -right rope/below right,
     -left axle/above, -right axle/above,
     -left wheel.south west/left, -right wheel.south east/right}
  \draw[shift=(s\anchor)]plot[mark=x]coordinates{(0,0)}
   node[inner sep=0pt,outer sep=5pt,\placement]
       {\scriptsize\ttfamily(s\anchor)};
\end{tikzpicture}
\end{document}

Output

enter image description here enter image description here

2
  • Thanks. I don't understand why there are two opening brackets [ in the code \def\tikzwaggon#1[{\pic#1[@waggon,} but no closing brackets. Where can I read about the use of such brackets?
    – Michael.H
    May 29 at 16:04
  • @Michael.H That's delimited macro definition on the TeX level. The first [ is part of the definition meaning that it will grab everything until the first [ which will replace #1 in the definition. The second one is part of the replacement text and will be closed by the ] in your document (the one right before ;). It was the easiest way for me to create something like a \waggon macro without having to create a custom parser. May 30 at 11:07
1

I fixed most of the bugs. I chose to make the parameters macros. You could use tikz keys or length registers instead, but macros are easier. The definitions will be local to the tikzpicture.

By default, nodes are positioned by the centers. You can use other anchors, but you will still need to calculate the locations.

\documentclass[border=10pt]{standalone}%
\usepackage{tikz}
\usetikzlibrary{arrows, calc}
\tikzset{
  mass/.style={rectangle, draw, thick, fill=gray!25},%
  wheel/.style={circle, draw, thick, fill=white},%
  wheelaxle/.style={circle, draw, fill},%
  rope/.style={blue, thick},%
  ground/.style={thick},%
  arrow/.style={-latex, thick},%
}
% global tikz-code here

\begin{document}
\begin{tikzpicture}[every node/.style={inner sep=0pt}]
  \def\height{4.2cm}% or use \pgfmathsetlengthmacro{\height}{4.2cm}
  \def\width{5cm}
  \def\wheel{1.1cm}% diameter
  \def\gap{0.6cm}
  \def\overlap{0.4cm}
  
   \draw[ground] (0,0) -- (9,0);%ground
   \node[draw, minimum width={\width}, minimum height={\height}] (mywagoon-mass) at (4.5, 0.5*\height+\overlap) {};
   \draw[rope] (mywagoon-mass.east) -- ++(1,0);
   \draw[rope] (mywagoon-mass.west) -- ++(-1,0);
   \path (mywagoon-mass.south west) ++(\gap+0.5*\wheel, 0.5*\wheel-\overlap)  node[wheel, minimum height={\wheel}] (mywagoon-wheel-2) {};
   \draw[arrow] (mywagoon-wheel-2.center) -- ++(2,0);
   %\draw[ground] (0,-6) -- (9,-6);%ground
   %\wagoon[name=mywagoon2, width=5, very thick, red] at (4.5,-6);%with defaults of other optional parameters and then additional very thick and red
\end{tikzpicture}
\end{document}

demo

You must log in to answer this question.

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