5

I am trying to improve this picture made in Word by using Tikz. I have made some advancements but there are some questions that kept me stuck.

4 bar mechanism parameters

  1. Regarding the angles, I need to draw a line at some point paralell to the X local axis. The same for \theta_0 but with respect to X fixed axis. This is well explained by @Jake in this post. However, I would like to specify the lenght of the segment.

  2. Once created those lines, how do I draw the angle mark? To draw this type of arrow I need somehow to refer to that line. In the MWE I have made the arrow for $\alpha$, but it was easy (once I learned how to do it) as I had the three coordinates. Is there some way to do it from the possible answer to Q1?

  3. How do I reposition the name of the vectors using draw?

This is my MWE:

\documentclass{article}
\usepackage{graphicx} % Required for inserting images
\usepackage{tikz}
\usetikzlibrary{angles, calc, arrows.meta,quotes}
\usepackage{kinematikz}

\begin{document}

\begin{figure}
    \centering
        \begin{tikzpicture}[
        arr/.style = {-Stealth, semithick},
        dot/.style = {circle,inner sep=1pt,fill,label={#1},name=#1},
        extended line/.style={shorten <=-#1},
        extended line/.default=1cm
        ]
            \draw [<->] (0,5) node[left]{$Y$} -- (0,0) -- (5,0) node[below]{$X$};  % Draws fixed RS
            \draw[dashed] (2,0) node[below] {$X_A$} -- (2,2);
            \draw[dashed] (0,2) node[left] {$Y_A$} -- (2,2);
            
            \coordinate [label={[label distance=0.5cm]235:$A$}] (A) at (2,2);
            \coordinate (B) at (3,5);
            \coordinate (C) at (6,7);
            \coordinate (D) at (9,4);
            \coordinate (E) at (4,8);
            \coordinate (M) at ($(B)!(E)!(C)$);    % E over BC line
            \coordinate (Y) at ($(A)!0.5!90:(D)$); % AD, scale factor 0.5 rotated 90º
            \coordinate (X) at ($(A)!0.5!0:(D)$);  % AD, scale factor 0.5 rotated 0º
            
            \draw (C) -- (E);
            \draw (A) -- (E);

            \fill [black] (B) circle [radius=2pt];
            \fill [black] ($(B)!(M)!(C)$) circle [radius=2pt];
            \fill [black] (C) circle [radius=2pt];
            \fill [red] (E) circle [radius=2pt];
            
            \draw (D)--(A)--(B) pic ["$\alpha$",draw,->, angle radius=1cm]{angle = D--A--B};

            \draw[arr] (B) to ["$\vec{r_b}$"] (C);
            \draw[arr] (D) to ["$\vec{r_c}$"] (C);
            \draw[arr] (B) to ["$\vec{r_{cx}}$"] (M);
            \draw[arr] (M) to ["$\vec{r_{cy}}$"] (E);
            \draw (B) -- +($(X)-(A)$); % Paralela a una línea que pasa por un punto dado
            \draw (D) -- +($(X)-(A)$);
            \draw (A) -- (6,2);
            
            \draw[orange, arr] (A) to ["$\vec{x}$"] (X); % X local axis
            \draw[orange, arr] (A) to ["$\vec{y}$"] (Y); % Y local axis

            \pic (pointA) at (A) {frame pivot rounded}; % Frame pivot A
            \pic (pointD) at (D) {frame pivot rounded}; % Frame pivot D

\end{tikzpicture}

    \caption{Caption}
    \label{fig:enter-label}

\end{figure}


\end{document}

enter image description here

Altough the package kinematikz may be useful for a more beautiful drawing of the mechanism I am using it just for the frame pivots.

2
  • 1
    3. to ["$\vec{x}$" at end] moves the node at the end of the to path. (You can also just use a node {…} after the target coordinate.) Oct 16, 2023 at 12:19
  • 2
    In regards to 1, something like the norm cs could help but nowadays we can use a sloped pic to draw a local coordinate system (here green) that is tangent to some line at some point . Oct 16, 2023 at 12:27

2 Answers 2

5

The pic sloped cs can be used to place a coordinate system tangent/parallel to (a point on) a line:

\tikzset{
  pics/sloped cs/.style args={#1:#2}{
    /tikz/sloped, /tikz/allow upside down,
    code={% styles sloped cs/x and sloped cs/y can be used to customize nodes
      \coordinate (-y) at (up:1) coordinate (-O) at (0,0)
       coordinate (-x) at (right:1); % sloped works best with reset cm:
      \draw[reset cm, pic actions, sloped, allow upside down=false]
        (-y) -- node[at start, left,  rotate=90, sloped cs/y/.try]{$#2$}
        (-O) -- node[at   end, below,            sloped cs/x/.try]{$#1$} (-x);}}}

It uses two paths: one to define the coordinates which follows the current transformation, i.e. tangent to the line, and one to actually draw the lines/arrows which no transformation active. This allows sloped to work properly.

Since both axis tips and the origin are named and the pic gets a name when it is used

pic (csA) [sloped cs, at start ] {sloped cs = \vec x_A : \vec y_A}
pic (csB) [sloped cs, shift=(B)] {sloped cs = \vec x_B : \vec y_B}

we can use the coordinate csB-x in drawing the θ₃ angle. You can see with the second coordinate system that I'm just using the tangent of the r₁ line but place it actually at B.

For the θ₀ angle I'm using a named coordinate right of A which is the end of the horizontal line right of A.

Except for A and D all coordinates are now dot nodes. This helps let the arrow tips and at the border of these dots. (Doing this for the pivots as well needs a bit more work and maybe digging through kinematikz' source.)

By the way, they are now placed sloped to the r₁ vector as well as their labels A and D.

I didn't like the way the rb vector covers rcx and the M dot so I've constructed a weird line – which is probably against all conventiones but I had fun …

Code

\documentclass[tikz]{standalone}
%\documentclass{article}
%\usepackage{graphicx} % Required for inserting images
\usepackage{tikz}
\usetikzlibrary{angles, bending, calc, arrows.meta, quotes}
\usepackage{kinematikz}
\tikzset{
  pics/sloped cs/.style args={#1:#2}{
    /tikz/sloped, /tikz/allow upside down,
    code={% styles sloped cs/x and sloped cs/y can be used to customize nodes
      \coordinate (-y) at (up:1) coordinate (-O) at (0,0)
       coordinate (-x) at (right:1); % sloped works best with reset cm:
      \draw[reset cm, pic actions, sloped, allow upside down=false]
        (-y) -- node[at start, left,  rotate=90, sloped cs/y/.try]{$#2$}
        (-O) -- node[at   end, below,            sloped cs/x/.try]{$#1$} (-x);}}}
\begin{document}
\begin{tikzpicture}[
  > = Stealth, arr/.style = {->, semithick}, arr <->/.style = {arr, <->},
  dot/.style = {circle, inner sep=+0pt, outer sep=+0pt, minimum size=+4pt, fill},
  sloped cs/.style = {arr <->, orange, scale=2, nodes={inner sep=+.3333em}},
  angle radius=1cm, angle eccentricity=1.3, % angle settings
  pics/angle/.append style={% every angle should be drawn
    /tikz/draw, % .3pt is half the linewidth of semithick
    /tikz/arrows={_[sep=+.3pt]}-{>[sep=+.3pt]}},
  pin distance=2mm,
  every label/.append style={shape=circle, inner sep=+.15em},
]
%\draw[help lines] (0,0) grid (12, 10);
\coordinate                   (A) at (2,2)             ;
\node[dot, "$B$" left]        (B) at (3,5)           {};
\node[dot, "$C$" above right] (C) at (6,7)           {};
\coordinate                   (D) at (9,4)             ;
\node[dot, fill=red, "$E$"]   (E) at (4,8)           {};
\node[dot, pin=$M$]           (M) at ($(B)!(E)!(C)$) {};

% global CS and stuff around A
\draw [<->] (0,5) node[left]{$Y$} |- (5,0) node[below]{$X$};  % Draws fixed RS
\draw[dashed] (A) -- (A|-0,0) node[below] {$X_A$};
\draw[dashed] (A) -- (A-|0,0) node[left] {$Y_A$};
\draw (A) -- +(right:2) coordinate (right of A);

% the two lines that aren't arrows
\draw (B) -- (E) -- (C);

% the \vec tors
\path[
  arr, nodes={inner sep=+.15em},
  L/.style={rotate=90, right}, L'/.style={rotate=90, left},
  R/.style={rotate=-90, right},
  bump around/.style args={##1 opposite ##2}{to path={
    --($(##1)!14pt!(\tikztostart)$)  -- ($(##1)!-5pt!(##2)$)
    --($(##1)!7pt!(\tikztotarget)$) -- (\tikztotarget) \tikztonodes}},
]
  (A) edge ["$\vec r_2$" ] (B)
  (D) edge ["$\vec r_4$"'] (C)
  [sloped]
%  (B) edge ["$\vec r_b$"] (C)
  (B) edge ["$\vec r_b$"', midway, rounded corners=3pt, bump around=M opposite E] (C)
  (B) edge ["$\vec r_{cx}$"] (M)
  (M) edge ["$\vec r_{cy}$"' L'] (E)
  (A) edge["$\vec r_1$"]
        pic (csA) [sloped cs, at start ] {sloped cs = \vec x_A : \vec y_A}
        pic (csB) [sloped cs, shift=(B)] {sloped cs = \vec x_B : \vec y_B}
        pic (pivotA) [behind path, at start, sloped] {frame pivot rounded}
        pic (pivotD) [behind path, at   end, sloped] {frame pivot rounded}
        node[below, shift=(pivotA-south), yshift=+-5pt] {$A$}
        node[below, shift=(pivotD-south), yshift=+-5pt] {$D$}
  (D)
 % now we have everything for the angles:
  pic ["$\alpha$"]{angle = D--A--B}
  pic ["$\theta_0$" yshift=-1pt, angle eccentricity=1.4]{angle = right of A--A--D}
  pic ["$\theta_3$"]{angle = csB-x--B--M}
;
\end{tikzpicture}
\end{document}

Output

enter image description here

3
  • I forgot to say that all scale keys as well as x and y can be used to change the size of the sloped cs. Oct 16, 2023 at 14:14
  • +1 Compact as always.
    – MS-SPO
    Oct 16, 2023 at 14:24
  • Many thanks for your quick response! The weird line is quite useful. Maybe the convention would have been to name correctly the vectors (my fault), i.e. $\vec{r}_{B/E}$, $\vec{r}_{B/E_x}$, $\vec{r}_{B/E_y}$ or $\vec{r}_{C/B}$.
    – Frank R.
    Oct 18, 2023 at 14:18
2

Ok, here's a little analysis and few changes, which hopefully put you on right track.

To assist myself, I changed or introduced:

  • the documentlcass, which is much nicer to use during development
  • put a help grid to better localize your coordinates (please REMOVE them later)
  • a simple loop to show all your coordinates (and a few new ones)
  • \foreach \l in {B,C,D,E,M,Y,X,P,Q} \node[blue] at ([shift=(90:.3)] \l) {\l};
  • kindly watch polar coordinates used to shift the labels upward a little)

Now let's have a look at some of the problems you address.

  1. Angles are just a picture (\pic). So my replacement may be more suitable. It leaves a void by intention, which you can easily fill, see below.

     %\draw (D)--(A)--(B) pic ["$\alpha$",draw,->, angle radius=1cm]{angle = D--A--B};
     % ~~~ changed : ~~~~~~~~~~~~~~
     \pic [red, "$\alpha$",draw,->, angle radius=1cm]{angle = D--A--B};
    

To put the missing vector try sth. like my untested:

\draw[arr] (A) -- (D) node [pos=0.5] {$\vec{r_1}$};
  1. For the parallel I switched to "make this a new coordinate" (++) AND stored its result in P.
        % ~~~ changed: ~~~~~
        \draw (B) -- ++($(X)-(A)$) coordinate (P); % Paralela a una línea...
        ...
        \draw (A) -- (6,2) coordinate (Q);% <<< changed

So later I can use it to draw the angles, like so:

    % ~~~ drawning missing angles ~~~~~~~~~
    \pic [red, "$\theta_3$",draw,->, angle radius=1cm, angle eccentricity=1.5]
        {angle = P--B--M};
    \pic [red, "$\theta_0$",draw,->, angle radius=13mm, angle eccentricity=1.5]
        {angle = Q--A--X};

I know, some answers may be missing, but you should be able to make progress now. BTW, have a read about polar coordinates in the pgfmanual. Because you rotate by a given angle, say about 30deg, you may want to use it often. I.e. using (30:35mm) rather than its cartesian counterpart.

You may also want to try \pic[rotate 30] ... with the kinematic Frame pivots.

result

%\documentclass{article}
\documentclass[10pt,border=3mm,tikz]{standalone}
%\usepackage{graphicx} % Required for inserting images
\usepackage{tikz}
\usetikzlibrary{angles, calc, arrows.meta,quotes}
\usepackage{kinematikz}

\begin{document}

%\begin{figure}
%    \centering
        \begin{tikzpicture}[
        arr/.style = {-Stealth, semithick},
        dot/.style = {circle,inner sep=1pt,fill,label={#1},name=#1},
        extended line/.style={shorten <=-#1},
        extended line/.default=1cm
        ]   
            % ~~~ REMOVE: help grid for my orientation ~~~~~~~~~
            \draw[help lines] (0,0) grid(10,10);

            \draw [<->] (0,5) node[left]{$Y$} -- (0,0) -- (5,0) node[below]{$X$};  % Draws fixed RS
            \draw[dashed] (2,0) node[below] {$X_A$} -- (2,2);
            \draw[dashed] (0,2) node[left] {$Y_A$} -- (2,2);
            
            \coordinate [label={[label distance=0.5cm]235:$A$}] (A) at (2,2);
            \coordinate (B) at (3,5);
            \coordinate (C) at (6,7);
            \coordinate (D) at (9,4);
            \coordinate (E) at (4,8);
            \coordinate (M) at ($(B)!(E)!(C)$);    % E over BC line
            \coordinate (Y) at ($(A)!0.5!90:(D)$); % AD, scale factor 0.5 rotated 90º
            \coordinate (X) at ($(A)!0.5!0:(D)$);  % AD, scale factor 0.5 rotated 0º
            
            \draw (C) -- (E);
            \draw (A) -- (E);

            \fill [black] (B) circle [radius=2pt];
            \fill [black] ($(B)!(M)!(C)$) circle [radius=2pt];
            \fill [black] (C) circle [radius=2pt];
            \fill [red]   (E) circle [radius=2pt];
            
            %\draw (D)--(A)--(B) pic ["$\alpha$",draw,->, angle radius=1cm]{angle = D--A--B};
            % ~~~ changed : ~~~~~~~~~~~~~~
            \pic [red, "$\alpha$",draw,->, angle radius=1cm]{angle = D--A--B};

            \draw[arr] (B) to ["$\vec{r_b}$"] (C);
            \draw[arr] (D) to ["$\vec{r_c}$"] (C);
            \draw[arr] (B) to ["$\vec{r_{cx}}$"] (M);
            \draw[arr] (M) to ["$\vec{r_{cy}}$"] (E);
%            \draw (B) -- +($(X)-(A)$); % Paralela a una línea que pasa por un punto dado
            % ~~~ changed: ~~~~~
            \draw (B) -- ++($(X)-(A)$) coordinate (P); % Paralela a una línea que pasa por un punto dado
            \draw (D) -- +($(X)-(A)$);
            \draw (A) -- (6,2) coordinate (Q);% <<< changed
            
            \draw[orange, arr] (A) to ["$\vec{x}$"] (X); % X local axis
            \draw[orange, arr] (A) to ["$\vec{y}$"] (Y); % Y local axis

            \pic (pointA) at (A) {frame pivot rounded}; % Frame pivot A
            \pic (pointD) at (D) {frame pivot rounded}; % Frame pivot D

            % ~~~ REMOVE: putting the nodes labels for my reference ~~~~~~~~~
            \foreach \l in {B,C,D,E,M,Y,X,P,Q} \node[blue] at ([shift=(90:.3)] \l) {\l};
            
            % ~~~ drawning missing angles ~~~~~~~~~
            \pic [red, "$\theta_3$",draw,->, angle radius=1cm, angle eccentricity=1.5]
                {angle = P--B--M};
            \pic [red, "$\theta_0$",draw,->, angle radius=13mm, angle eccentricity=1.5]
                {angle = Q--A--X};

\end{tikzpicture}
%    \caption{Caption}
%    \label{fig:enter-label}
%
%\end{figure}
\end{document}
4
  • 1
    Very good tutorial. Remark you did not use dot and extended line.
    – pascal974
    Oct 16, 2023 at 13:58
  • Thank you. As you see: nobody is perfect ;-)
    – MS-SPO
    Oct 16, 2023 at 14:23
  • 1
    Many thanks for your answer. It solves my quiestions in a very instructive way, which is much appreciated. I will combine both answers as there are elements in both of them that really improve my first attempt.
    – Frank R.
    Oct 18, 2023 at 14:21
  • @FrankR., thank you, that's good to read. If you like, you can post your combined result here as well. Would be interesting to see.
    – MS-SPO
    Oct 18, 2023 at 15:48

You must log in to answer this question.

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