Drawing planar mechanisms in tikz

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.

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)!(M)!(C)$) 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}


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

• 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
• 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

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

• 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. 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}$. Oct 18, 2023 at 14:18

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.

%\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)!(M)!(C)$) 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}

• Very good tutorial. Remark you did not use dot and extended line. Oct 16, 2023 at 13:58
• Thank you. As you see: nobody is perfect ;-) Oct 16, 2023 at 14:23
• 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. 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. Oct 18, 2023 at 15:48