[Tex/LaTex] How to make this free body diagram with a non-straight force line using tikzpicture environment

tikz-pgftikz-styles

Please consider the following MWE adapted from this fantastic example of Kjell Magne Fauske's free body diagram:

\documentclass{article}

\usepackage{tikz}           % From http://www.texample.net/tikz/examples/free-body-diagrams/
\usetikzlibrary{scopes}
\begin{document}

\def\iangle{0} % Angle of the inclined plane

\def\down{-90}
\def\arcr{0.5cm} % Radius of the arc used to indicate angles

\begin{tikzpicture}[
    scale=4,
    force/.style={->,draw=blue,fill=blue},
    axis/.style={densely dashed,gray,font=\small},
    M/.style={rectangle,draw,fill=lightgray,minimum size=0.5cm,thin},
    m/.style={rectangle,draw=black,fill=lightgray,minimum size=0.3cm,thin},
    plane/.style={draw=black,fill=blue!10},
    string/.style={draw=red, thick},
    pulley/.style={thick},
]

    %% Free body diagram of M
    \begin{scope}[rotate=\iangle]
        \node[M,transform shape] (M) {};
        % Draw axes and help lines

        {[axis,->]
            \draw (0,-1) -- (0,2) node[right] {$+y$};
            \draw (M) -- ++(2,0) node[right] {$+x$};    % mental note for me: change "right" to "above"
        }

        % Forces
        {[force,->]
            % Assuming that Mg = 1. The normal force will therefore be cos(alpha)
            \draw (M.center) -- ++(0,{cos(\iangle)}) node[above right] {$\vec N$};
            \draw (M.west) -- ++(-1,0) node[left] {$\vec f_r$};
        }

    \end{scope}
    % Draw gravity force. The code is put outside the rotated
    % scope for simplicity. No need to do any angle calculations. 
    \draw[force,->] (M.center) -- ++(0,-1) node[below] {$\vec P$};
    %%
\end{tikzpicture}

\end{document}

Example of body free diagram

With your huge help, I would like to know how to

  1. add a line with slope (e.g. with an inclination of 53º <- with the label and the correct slope). Note that the source already has a code for the angle, it may be the same in this case;
  2. make proportional axis and not "from wherever you are, go above/right by 2", e.g. a 30 ~ 40% more long than the length of the force lines (I ask this because if scale=4 then the axis lines are too large than the force lines);
  3. aditionally add a "floor" with black diagonal lines (maybe this Milo's excellent answer or this marmot's awesome response helps?);
  4. the friction force line f_r in front of the body and not behind;
  5. the possibility of descompose the forces that are not horizontal/vertical (maybe with the same style of the axis line, idk, be creative with format!).

I want something like this:

What I want

If possible, I would like you to keep the code format of the MWE so that I do not have to adapt to another code style, but add to the current one.

If you think that the colors are monotonous you can propose darker grays or other styles!

Many thanks!

Best Answer

My humble attempt using arrows (which got superseded by arrows.meta; see below for a version using that library), decoration.markings and angles libraries.

\documentclass[tikz,border=2mm]{standalone} 

\usetikzlibrary{arrows,decorations.markings,angles}

\def\Fangle{53}
\def\Flength{5}
\def\iangle{20}
\def\Plength{2}
\def\Gwidth{5}
\def\Gthick{3pt}
\def\Gstep{4pt}
\def\coordwd{1}
\usepackage{siunitx}

\begin{document}
\begin{tikzpicture}
  [
    ,force/.style={>=latex',->,draw=blue,fill=blue}
    ,force component/.style={>=latex',->,draw=gray,fill=gray}
    ,M/.style={rectangle,draw,fill=lightgray,minimum size=0.5cm,thin}
    ,note/.style={font=\small}
    ,ground/.style={black,postaction={ground hatch}}
    ,ground hatch/.style=
      {
        decorate,
        decoration=
          {
            ,markings
            ,mark =
              between positions 0 and 1 step \Gstep
              with{\draw[darkgray] (-\Gthick,-\Gthick) -- (0,0);}
          }
      }
    ,my angles/.style=
      {
        ,draw=green!70!black
        ,->
        ,angle radius=9mm
        ,angle eccentricity=1.3
        ,pic text=#1
        ,font = \small
      }
    ,coord/.style={dashed,gray,>=latex',->,transform shape}
  ]
  \begin{scope}[rotate=\iangle]
    \node[M,transform shape] (M) {};
    \draw[force] (M.center) ++(\Fangle+90:\Flength) coordinate (F)
      --node[at start,above left,note]{$\vec{F}$} (M.center);
    \draw[force component] (F)
      --node[at end,above left,gray,note,transform shape,rotate=-90]
        {$\Vert\vec{F}\Vert\cos\SI{\Fangle}{\degree}$}
      (F|-M.center) coordinate (fr);
    \draw[force component] (F) 
      --node[at end,above left,gray,note,transform shape]
        {$\Vert\vec{F}\Vert\sin\SI{\Fangle}{\degree}$}
      (F-|M.center) coordinate (N);
    \draw[force] (M.center)
      --node[at end,below,note]{$\vec{f}_r$} (fr);
    \draw[force] (M.center)
      --node[at end,right,note]{$\vec{N}$} (N);
    \draw[ground] (M.south) ++(-\Gwidth/2,0) -- ++(\Gwidth,0) coordinate (G);
    \path (M.center) coordinate (Mc)
      pic[my angles=\SI\Fangle\degree]
      {angle=N--Mc--F};
    \draw[coord] (N) --node[at end,above]{$+y$} ++(0,\coordwd);
    \draw[coord] (M.east) --node[at end,right]{$+x$} ++(\coordwd,0);
  \end{scope}
  \draw[force] (M.center) --node[at end,below,note]{$\vec{P}$} ++(0,-\Plength);
  \draw[dashed,darkgray] (M.south) -- ++(2,0) coordinate (H);
  \path (M.south) coordinate (Ms)
    pic[my angles=\SI\iangle\degree]
    {angle=H--Ms--G};
\end{tikzpicture}
\end{document}

enter image description here

Changing the 53° label to the position you want, also using arrows.meta instead of arrows:

\documentclass[tikz,border=2mm]{standalone} 

\usetikzlibrary{arrows.meta,decorations.markings,angles}

\def\Fangle{53}
\def\Flength{5}
\def\iangle{20}
\def\Plength{2}
\def\Gwidth{5}
\def\Gthick{3pt}
\def\Gstep{4pt}
\def\coordwd{1}
\usepackage{siunitx}

\begin{document}
\begin{tikzpicture}
  [
    ,force/.style={>=Stealth,->,draw=blue,fill=blue}
    ,force component/.style={>=Stealth,->,draw=gray,fill=gray}
    ,M/.style={rectangle,draw,fill=lightgray,minimum size=0.5cm,thin}
    ,note/.style={font=\small}
    ,ground/.style={black,postaction={ground hatch}}
    ,ground hatch/.style=
      {
        decorate,
        decoration=
          {
            ,markings
            ,mark =
              between positions 0 and 1 step \Gstep
              with{\draw[darkgray] (-\Gthick,-\Gthick) -- (0,0);}
          }
      }
    ,my angles/.style=
      {
        ,draw=green!70!black
        ,->
        ,angle radius=9mm
        ,angle eccentricity=1.3
        ,pic text=#1
        ,font = \small
      }
    ,coord/.style={dashed,gray,>=Stealth,->,transform shape}
  ]
  \begin{scope}[rotate=\iangle]
    \node[M,transform shape] (M) {};
    \draw[force] (M.center) ++(\Fangle+90:\Flength) coordinate (F)
      --node[at start,above left,note]{$\vec{F}$} (M.center);
    \draw[force component] (F)
      --node[at end,above left,gray,note,transform shape,rotate=-90]
        {$\Vert\vec{F}\Vert\cos\SI{\Fangle}{\degree}$}
      (F|-M.center) coordinate (fr);
    \draw[force component] (F) 
      --node[at end,above left,gray,note,transform shape]
        {$\Vert\vec{F}\Vert\sin\SI{\Fangle}{\degree}$}
      (F-|M.center) coordinate (N);
    \draw[force] (M.center)
      --node[at end,below,note]{$\vec{f}_r$} (fr);
    \draw[force] (M.center)
      --node[at end,right,note]{$\vec{N}$} (N);
    \draw[ground] (M.south) ++(-\Gwidth/2,0) -- ++(\Gwidth,0) coordinate (G);
    \path (M.center) coordinate (Mc)
      pic[my angles=\SI\Fangle\degree]
      {angle=fr--F--Mc};
    \draw[coord] (N) --node[at end,above]{$+y$} ++(0,\coordwd);
    \draw[coord] (M.east) --node[at end,right]{$+x$} ++(\coordwd,0);
  \end{scope}
  \draw[force] (M.center) --node[at end,below,note]{$\vec{P}$} ++(0,-\Plength);
  \draw[dashed,darkgray] (M.south) -- ++(2,0) coordinate (H);
  \path (M.south) coordinate (Ms)
    pic[my angles=\SI\iangle\degree]
    {angle=H--Ms--G};
\end{tikzpicture}
\end{document}

enter image description here