Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.)

share|improve this question
    
Good looking generally means fractal. –  John Kormylo Nov 29 '13 at 15:17
    
Yes that's precisely what I mean. –  Guido Jorg 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
add comment

2 Answers

up vote 4 down vote accepted

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}

enter image description here

share|improve this answer
    
How do I remove the arrowheads, if I don't need them? –  Guido Jorg Jan 12 at 5:30
1  
@GuidoJorg You may remove the -stealth option. –  Paul Gaborit Jan 12 at 8:25
add comment

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}{%
 \global\advance\gaussF by\@ne
 \ifodd\gaussF
  \pgfmathrnd@%
  \pgfmathadd@{.0000001}{\pgfmathresult}%
  \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}
 \pgfmathadd{1}{-\fracF}%
 \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%
   \global\advance\c@fracI by \fracN
   \edef\fracM{frac\arabic{fracI}}
   \global\advance\c@fracI by \fracN
   \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}

fractal

share|improve this answer
    
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. –  Guido Jorg Jan 12 at 5:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.