[Tex/LaTex] How to draw a pretty dog leash from A to B

funtikz-pgf

I need help to draw a dog leash from A to B that seems to be 8m long. The house is 3 by 5 m.

enter image description here

\documentclass[tikz]{standalone}
\usepackage{graphicx}
\usetikzlibrary{}

\begin{document}
\begin{tikzpicture}

\draw (0,0) rectangle (5,3) ;

\fill (1,3) circle (1pt) node[anchor=south] {$A$} ;

\begin{scope}[shift={(7,4)}]
\node {\includegraphics[scale=.2]{idefix}} ;
\fill[red] (-.26,-.02) circle (.3pt) node[anchor=west] {$B$} ;
\end{scope}

\end{tikzpicture}

\end{document} 

Best Answer

The question is interesting. So you want a "loose" curve which joins points (A) and (B) and whose length is 8 units.

Obviously, the difficult part is to ensure that the length is 8 units (or at least close to that amount). The general problem depends on which curve is chosen (See Wikipedia's arc length article), but in general there is no closed solution.

First I tried to draw a circunference arc and trying to calculate (with paper and pencil) the required angle and radius to provide a length of 8, given that the chord (distance (A)--(B)) is 6 with your current settings. After a while, I was fed up (too much time since I used paper and pencil for the last time :-)) and went for another approach.

Through this answer I found a python library which can compute the length of a Bezier curve (which is also a difficult problem usually solved by approximation), and after some trial and error, I found a solution which is aesthetically pleasing and has approximately 8 units of length as required:

\usetikzlibrary{calc}

\begin{tikzpicture}

\draw (0,0) rectangle (5,3) ;
\coordinate (A) at (1,3);
\coordinate (B) at (7,4);

\fill (A) circle (1pt) node[anchor=south] {$A$} ;

\begin{scope}[shift={(B)}]
%\node (idefix) {{idefix}} ;
\fill[red] (-.26,-.02) circle (.3pt) node[anchor=west] {$B$} ;
\end{scope}

\draw[blue,thick] (A) .. controls (4,6) and (8,0) .. (B);

\end{tikzpicture}

Result:

Result

Length computation:

>>> from pyx import path, unit
>>> bez = path.curve(1,3,4,6,8,0,7,4)
>>> unit.tocm(bez.arclen())
7.955089832696614

Update: To give a more natural look to the rope, and under the assumption that its lenght will not change too much, a "random steps" decoration can be used:

\usetikzlibrary{calc,decorations,decorations.pathmorphing}

\begin{tikzpicture}

\draw (0,0) rectangle (5,3) ;
\coordinate (A) at (1,3);
\coordinate (B) at (7,4);

\fill (A) circle (1pt) node[anchor=south] {$A$} ;

\begin{scope}[shift={(B)}]
%\node (idefix) {{idefix}} ;
\fill[red] (-.26,-.02) circle (.3pt) node[anchor=west] {$B$} ;
\end{scope}

\draw[blue,thick,decorate,decoration={random steps}, rounded corners=1mm] (A) .. controls (4,6) and (8,0) .. (B);

\end{tikzpicture}

Result:

Result