Arbitrary Ragged Curves for Phase Diagram in TikZ

How can one draw a good looking curved random line extending along a diagonal connecting two arbitrary nodes in TikZ?

(Also, how do I add arrowheads like I would usually do, or do I have to create an arrowhead at a point and superpose it over the endpoint, separately?)

(There are some idea on how to do a good looking vertical line or horizontal line in this topic Drawing randomly ragged lines in technical drawings . Please use the MWE from there.

\documentclass[12pt]{article} % SIZE OF FONT AND ITS LAYOUT ON EACH PAGE.
\usepackage[top = 1in, bottom = 1in, left = 1in, right = 1in]{geometry}
\usepackage{amsmath, booktabs, graphicx, setspace}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz,tkz-graph,tikz-cd} % DIAGRAMS.
\usetikzlibrary{arrows, calc, decorations.markings}
\usetikzlibrary{calc}

\newcommand\irregularline[2]{%
let \n1 = {(rand*(#1)} in
+(0,\n1)
\foreach \a in {0.1,0.2,...,#2}{
let \n1 = {rand*(#1)} in
-- +(\a,\n1)
}}  % #1=seed, #2=length of horizontal line

% This is code for a horizontal random line that I like.
% How to make this sort of line connect two arbitrary points,
% and perhaps, how to make it curve in a natural way?

\begin{document}

\begin{figure}[h]
\begin{center}
\begin{tikzpicture}[scale=1.8,auto]

% replace with randomly ragged line that curves

\draw [-,line width=1pt] (0,0) edge (3,3);

\end{tikzpicture}
\end{center}
\caption{CAPTION GOES HERE}
\label{fig:FIGURE NAME GOES HERE}

\end{figure}
\end{document}


(Using How to draw a irregular circle(shape)?, and this, I am trying to make phase diagrams instead of drawing them by hand.)

• Good looking generally means fractal. – John Kormylo Nov 29 '13 at 15:17
• Yes that's precisely what I mean. – Gottfried William Dec 1 '13 at 11:47
• My preferred style is to do calculations in C and typesetting in LaTeX. But since giving you a simple implementation of a fractal or C code wouldn't do you much good, I tried to implement it using the pgfmath package. Even constantly converting number into text and back again, Tikz just isn't set up to do this. It would be easier to use straight TeX. At least then I would be able to use \expandafter and know what was going on. – John Kormylo Dec 1 '13 at 21:06

Here is another fractal solution using Tikz (and not pgf).

I define a new to path style named fractal line with two parameters:

1. the ratio of length to move the middle of each segment.

2. the minimum length to apply the recurrence.

Example of usage to draw an fractal line between (0,0) and (5,0):

\draw (0,0) to[fractal line=.1 and 1mm] (5,0);


The complete code:

\documentclass[convert={size=480},margin=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
fractal line/.style args={#1 and #2}{%
% #1 is ratio of length to move the middle of each segment
% #2 is the minimum length to apply the recurrence
to path={
let
\p1=(\tikztostart), % start point
\p2=(\tikztotarget), % end point
\n1={veclen(\x1-\x2,\y1-\y2)}, % distance
\p3=($(\p1)!.5!(\p2)$), % middle point
\p4=(rand*#1*\n1,rand*#1*\n1), % random vector
\p5=(\x3+\x4,\y3+\y4) % random moved middle point
in \pgfextra{
\pgfmathtruncatemacro\mytest{(\n1<#2)?1:0}
\ifnum\mytest=1 %
\tikzset{fractal line/.style args={#1 and #2}{line to}}
\fi
} to[fractal line=#1 and #2] (\p5) to[fractal line=#1 and #2] (\p2)
},
},
}

\begin{document}
\begin{tikzpicture}
\draw[rounded corners=1mm,-stealth] (0,0) to[fractal line=.05 and 1cm] (10,0);
\draw[rounded corners=.3mm,-stealth] (0,0) to[fractal line=.2 and 3mm] (4,4);
\end{tikzpicture}
\end{document}


• How do I remove the arrowheads, if I don't need them? – Gottfried William Jan 12 '14 at 5:30
• @GuidoJorg You may remove the -stealth option. – Paul Gaborit Jan 12 '14 at 8:25

In answer to your original question, the following draws a fractal path connecting two points. In this case (0,0) to (3,3)

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{calc}

% zero mean Gaussian random number with variance=1
\newcount\gaussF
\edef\gaussR{0}
\edef\gaussA{0}

\makeatletter
\pgfmathdeclarefunction{randgauss}{0}{%
\ifodd\gaussF
\pgfmathrnd@%
\pgfmathln@{\pgfmathresult}%
\pgfmathmultiply@{-2}{\pgfmathresult}%
\pgfmathsqrt@{\pgfmathresult}%
\global\let\gaussR=\pgfmathresult%radius = $sqrt(-2*ln(rnd))$
\pgfmathrnd@%
\pgfmathmultiply@{360}{\pgfmathresult}%
\global\let\gaussA=\pgfmathresult%angle = $360*rnd$
\pgfmathcos@{\pgfmathresult}%
\pgfmathmultiply@{\pgfmathresult}{\gaussR}%
\else
\pgfmathsin@{\gaussA}%
\pgfmathmultiply@{\gaussR}{\pgfmathresult}%
\fi
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{fracI}
\newcount\fracN

\edef\fracF{0.5}% Controls shape of fractal.  Must be < 1.
\edef\fracNPT{64}% number of points to plot

\begin{document}

\begin{center}
\makeatletter
\begin{tikzpicture}
\global\let\fracS = \pgfmathresult%
\global\fracN = \fracNPT
\global\divide\fracN by\tw@
\coordinate (frac0) at (0,0);% starting point
\coordinate (frac\fracNPT) at (3,3);% ending point
% calculate perpendicular.  Can replace 1cm with scale factor.
\coordinate (fracP) at ($(frac0)!1cm!90:(frac\fracNPT) - (frac0)$);

\global\c@fracI = \z@
\edef\fracR{frac0}
\loop\ifnum\fracN > \z@
\ifnum\c@fracI < \fracNPT\relax
\global\let\fracL = \fracR%
\edef\fracM{frac\arabic{fracI}}
\edef\fracR{frac\arabic{fracI}}
\pgfmathmultiply{\fracS}{randgauss}%
\global\let\fracY = \pgfmathresult%
\coordinate (\fracM) at ($(\fracL)!0.5!(\fracR) + \fracY*(fracP)$);
\else
\global\divide\fracN by\tw@
\pgfmathmultiply{\fracS}{\fracF}%
\global\let\fracS = \pgfmathresult%
\global\c@fracI = \z@
\edef\fracR{frac0}
\fi
\repeat
% now draw line
\setcounter{fracI}{0}
\edef\fracR{frac0}
\loop\ifnum\c@fracI < \fracNPT\relax
\stepcounter{fracI}
\global\let\fracL = \fracR
\edef\fracR{frac\arabic{fracI}}
\draw (\fracL) -- (\fracR);
\repeat
\end{tikzpicture}
\makeatother
\end{center}

\end{document}


• I think this is good code also. The 1st answer is a bit shorter to use, but I would give both answers the acceptance checkmark if I could. – Gottfried William Jan 12 '14 at 5:29