1

I am trying to draw a rectangle on a specific path, that is, I have an inclined line from A to B and I need to draw a rectangle using that angle.

This is the diagram I am trying to replicate:

enter image description here

and I am having some trouble drawing the rectangle for the arm (and subsequently the ones that align with the path from C to B).

Here the part of the code I have so far:

\documentclass[crop=true]{standalone}
\usepackage{tikz,pgf,import,pgfplots}
\usetikzlibrary{intersections}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\usetikzlibrary{fit} 
\usetikzlibrary{calc}
\pgfplotsset{compat=1.3} 

\begin{document}
\centering
\begin{tikzpicture}

\draw[->] (-40mm,0) -- (15mm,0) node[right] {$x$} coordinate(x axis);
\draw[->] (0,-5mm) -- (0,15mm) node[above] {$y$} coordinate(y axis);
\draw[help lines, step=0.5cm] (-55mm,-15mm) grid (20mm,60mm);
\filldraw[fill=green!20!white, draw=green!50!black] (8mm,0mm)
arc [start angle=0, end angle=-180, radius=8mm] -- (-8mm,3mm)--(8mm,3mm)--cycle;
\node [anchor=south,rectangle,draw=black!50,fill=black!20,inner sep=0pt,minimum width=3mm, minimum height=2mm] at (0mm,3mm) {};

\coordinate (P1) at (-27mm,8mm);
\coordinate (Float) at (0mm,3mm);
\draw (P1) rectangle +(3mm,52mm);
\draw let \p1 = ($ (P1) + (-1.5mm,8mm) $),
          \p2 = ($ (\p1) + (0mm,27.33mm) $)
        in 
            (\p1) coordinate[label=below left:\textcolor{blue}{$A$}] (A)
            (\p2) coordinate[label=below right:\textcolor{blue}{$B$}](B);
\path[name path=arm line] (Float) -- ($ (Float) !1.5! (A) $);
\path[name path=C] (A) circle[radius=13.33mm];
\path [name intersections={of= arm line and C, by={x1,x2}}];
\coordinate [label=above left:\textcolor{blue}{$C$}] (C) at (x1);

\draw (Float) -- (C) -- (B);
\foreach \point in {A,B,C}
    {
    \filldraw[fill=white,draw=black] (\point) circle (1mm);
    \filldraw[fill=black,draw=black] (\point) circle (0.3mm);
    }
\node (arm) [rotate=150, draw=black,thick,rounded corners, inner sep=2mm, fit=(C)(Float)] {};

\end{tikzpicture}
\end{document}

I also tried using: \draw[rotate=150] (Float) rectangle (C);

but it does not work.

Any guidance is always welcome.

Cheers! Juan

3 Answers 3

1

This may not be an elegant solution, but you can indeed use \draw combined with layers to achieve this:

\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{intersections,arrows.meta,positioning,fit,calc}
\pgfplotsset{compat=1.18} 

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\begin{document}
    \centering
    \begin{tikzpicture}[>=Stealth,x=1mm,y=1mm]
        \filldraw[fill=green!20!white, draw=green!50!black] (8,0)
        arc [start angle=0, end angle=-180, radius=8mm] -- (-8,3)-- (8,3) -- cycle;
        \node[anchor=south,rectangle,draw=black!50,fill=black!20,inner sep=0pt,minimum width=3mm, minimum height=2mm] at (0,3) {};
        
        %Coordinate system
        \draw[->] (-40mm,0) -- (15mm,0) node[right] {$x$} coordinate(x axis);
        \draw[->] (0,-5mm) -- (0,15mm) node[above] {$z$} coordinate(y axis);
        \coordinate (P1) at (-27,8);        
        \coordinate (Float) at (0,3);
        \coordinate[label=below left:\textcolor{blue}{$A$}] (A) at ($ (P1) + (-1.5,8) $);
        \coordinate[label=below right:\textcolor{blue}{$B$}] (B) at ($ (A) + (0,27.33) $);
        
        %Calculate position of C
        \path[name path=arm line] (Float) -- ($ (Float) !1.5! (A) $);
        \path[name path=C] (A) circle[radius=13.33mm];
        \path [name intersections={of= arm line and C, by={x1,x2}}];
        \coordinate[label=above left:\textcolor{blue}{$C$}] (C) at (x1);
        
        \foreach \point in {A,B,C}
        {
            \draw[fill=white] (\point) circle (1);
            \filldraw (\point) circle (0.3);
        }
        
        \begin{pgfonlayer}{background}
            \draw (P1) rectangle +(3,52);
            \draw[line width=7.5pt] ($(Float)!1.055!(C)$) -- ($(C)!1.035!(Float)$);
            \draw[gray!20,line width=6pt] ($(Float)!1.05!(C)$) -- ($(C)!1.03!(Float)$);
        \end{pgfonlayer}
    \end{tikzpicture}
\end{document}

enter image description here

There are definitely better ways to achieve this, e.g. using the angle between the three points that tikz can calculate for you.

1
  • As you said, probably is not the most elegant solution, but definitely, the one that helps me. Commented Sep 22, 2021 at 15:30
2

I would use the calc notation to build the rectangle myself with four lines:

\documentclass[tikz, border=1 cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (1,5);
\coordinate (B) at (8,2);
\fill (A) circle[radius=0.1] node[below]{A};
\fill (B) circle[radius=0.1] node[below]{B};
%calc notation
\draw ($ (A)!.1!135:(B) $) -- ($ (A)!.1!-135:(B) $) -- ($ (B)!.1!135:(A) $) -- ($ (B)!.1!-135:(A) $) -- cycle;
%alternative with a node
\draw[red] let \p1=($(B)-(A)$), \n1={atan2(\y1,\x1)} in node[draw, minimum width=10 cm, minimum height=2 cm, xshift=4cm, rotate around={\n1:(A)}] at (A){};
\end{tikzpicture}
\end{document}

Two nodes with two rectangles

($ (A)!.1!135:(B) $) means a point near (A) moved 0.1 in direction of 135 deg relative to the (A), (B) line.

1
  • Thanks hpekristiansen! Commented Sep 22, 2021 at 15:31
2

Your angle is not 150 ° you have to determine it before

I added the calculation of the angle from the coordinates of two points (I refer you to the documentation)

I took the opportunity to set a scope that will allow you to draw in the inclined benchmark.

We notice that the nodes do not turn in the scope (even with transform shape)

\documentclass[crop=true]{standalone}
\usepackage{tikz,pgf,import,pgfplots}
\usetikzlibrary{intersections}
\usetikzlibrary{arrows}
\usetikzlibrary{positioning}
\usetikzlibrary{fit} 
\usetikzlibrary{calc}
\pgfplotsset{compat=1.3} 

\begin{document}
\centering
\begin{tikzpicture}

\draw[->] (-40mm,0) -- (15mm,0) node[right] {$x$} coordinate(x axis);
\draw[->] (0,-5mm) -- (0,15mm) node[above] {$y$} coordinate(y axis);
\draw[help lines, step=0.5cm] (-55mm,-15mm) grid (20mm,60mm);
\filldraw[fill=green!20!white, draw=green!50!black] (8mm,0mm)
arc [start angle=0, end angle=-180, radius=8mm] -- (-8mm,3mm)--(8mm,3mm)--cycle;
\node [anchor=south,rectangle,draw=black!50,fill=black!20,inner sep=0pt,minimum width=3mm, minimum height=2mm] at (0mm,3mm) {};

\coordinate (P1) at (-27mm,8mm);
\coordinate (Float) at (0mm,3mm);
\draw (P1) rectangle +(3mm,52mm);
\draw let \p1 = ($ (P1) + (-1.5mm,8mm) $),
          \p2 = ($ (\p1) + (0mm,27.33mm) $)
        in 
            (\p1) coordinate[label=below left:\textcolor{blue}{$A$}] (A)
            (\p2) coordinate[label=below right:\textcolor{blue}{$B$}](B);
\path[name path=arm line] (Float) -- ($ (Float) !1.5! (A) $);
\path[name path=C] (A) circle[radius=13.33mm];
\path [name intersections={of= arm line and C, by={x1,x2}}];
\coordinate [label=above left:\textcolor{blue}{$C$}] (C) at (x1);

\draw (Float) -- (C) -- (B);
\foreach \point in {A,B,C}
    {
    \filldraw[fill=white,draw=black] (\point) circle (1mm);
    \filldraw[fill=black,draw=black] (\point) circle (0.3mm);
    }

\newcommand{\pgfextractangle}[3]{%
    \pgfmathanglebetweenpoints{\pgfpointanchor{#2}{center}}
                              {\pgfpointanchor{#3}{center}}
    \global\let#1\pgfmathresult  
}

\pgfextractangle{\angle}{C}{A}

\begin{scope}[rotate=\angle,transform canvas]
\draw (C) -- ++(5,0);
\node (arm) [ rotate=\angle,draw=black,thick,rounded corners, inner sep=2mm, fit=(C)(Float)] {};
\end{scope}



\end{tikzpicture}
\end{document}

enter image description here

2
  • Hi Rpapa. Thanks for your help. could you help me to understand what does this option in the library calc: \usetikzlibrary{calc}[![enter image description here][1]][1] Cheers Commented Sep 22, 2021 at 15:27
  • it's a bug! (Je corrige)
    – rpapa
    Commented Sep 22, 2021 at 19:34

You must log in to answer this question.

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