# Generating Random arrows in tikz

I would like to draw this figure :

Hence, I resort to TikZ. But, it seems to be very difficult drawing arrows precisely in TikZ with the precise locations (x,y). I have achieved this:

Here is the MWE:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\filldraw[color=gray] (1,0) rectangle (10,5);
\draw[->, line width=2pt, color=red] (2,1) -- (3,1);
\draw[->, line width=2pt, color=red] (2,2) -- (3,2.5);
\draw[->, line width=2pt, color=red] (3,2) -- (30:3);
\end{tikzpicture}
\end{document}


Now, my question is

## Note:

If not Tikz, pstricks or MetaPost will also do. For now, Asmptote will not work because there seems an error in the execution in my system.

-
I appreciate you accepted my answer, but may suggest you to wait a little longer before accepting an answer? I am sure some other answers will show up. –  Gonzalo Medina May 22 '14 at 15:16
@GonzaloMedina Can you please edit your answer as the picture in my question. The spacing between arrows is much less. How to improve that? –  subham soni May 22 '14 at 15:24
I am afraid I don't completely understand. What do you want to change? –  Gonzalo Medina May 22 '14 at 15:25
Please see the figure "I want to draw this:". In that, the spacing between the arrows is much. How to achieve this spacing? –  subham soni May 22 '14 at 15:27
I'll have to think about this. In my current answer the starting point for each arrow as well as the ending point are randomly chosen so, in its present form, it's not easy to control the spacing. –  Gonzalo Medina May 22 '14 at 15:33

## Updated version (without crossing):

A possibility with random colors, widths, directions, lengths; the image was produced using

\RandArrow

\def\Columns{10}
\RandArrow[80]


The code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\def\maxArrow{30}
\def\Columns{6}

\newcommand\randomarrow{
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\edef\R{\pdfuniformdeviate 255}
\edef\G{\pdfuniformdeviate 255}
\edef\B{\pdfuniformdeviate 255}
\xdefinecolor{mycolor}{RGB}{\R,\G,\B}
\tikz\draw[->,line width=2pt*rnd+1pt,color=mycolor]
(rnd,rnd) -- ++(rnd*360:rnd+0.2);
}
\newcommand\RandArrow[1][30]{%
\def\maxArrow{#1}
\begin{tikzpicture}
\foreach [count=\i] \val in {1,...,\maxArrow}
{
\path
let \n{row}={int(mod(\i -1, \Columns))},
\n{col}={ int( ( \i - 1 ) / (-\Columns) ) }
in
(\n{row}, \n{col}) rectangle  +(1,1)
+(0.5, 0.5) node{\randomarrow};
}
\begin{pgfonlayer}{background}
\draw[orange!70!black,line width=1pt,fill=yellow!15]
(current bounding box.north west)
rectangle
(current bounding box.south east);
\end{pgfonlayer}
\end{tikzpicture}%
}

\begin{document}

\RandArrow

\def\Columns{10}
\RandArrow[80]

\end{document}


The idea to avoid crossing arrows is to have a grid and place each arrow in one of the squares of the grid.

1. \maxArrows allows to specify the number of arrows (initially set to 30).

2. \Columns controls the number of rows of the grid (initially set to 6).

3. \randomarrow draws an arrow; the width, length, color and direction are chosen randomly using rnd; the length will only be (in the worst case) 0.2cm larger than the width of the square; this is to prevent arrows from having zero length.

4. The main command is \RandArrow with an optional argument allowing to decide the number of arrows to be drawn; the default value is 30.

5. As suggested by Paul Gaborit in his answer, \pgfmathsetseed{\pdfuniformdeviate 10000000} was used in the definition of \randomarrow to change the seed used by the pseudo-random generator at each compilation.

Introducing some randomness in the grid gives better results:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\def\maxArrow{30}
\def\Columns{6}

\newcommand\randomarrow{
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\edef\R{\pdfuniformdeviate 255}
\edef\G{\pdfuniformdeviate 255}
\edef\B{\pdfuniformdeviate 255}
\xdefinecolor{mycolor}{RGB}{\R,\G,\B}
\tikz\draw[->,line width=2pt*rnd+1pt,color=mycolor]
(rnd,rnd) -- ++(rnd*360:rnd+0.1);
}
\newcommand\RandArrow[1][30]{%
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\def\maxArrow{#1}
\begin{tikzpicture}
\foreach [count=\i] \val in {1,...,\maxArrow}
{
\path
let \n{row}={ int(mod(\i -1, \Columns))},
\n{col}={ int( ( \i - 1 ) / (-\Columns) ) }
in
(\n{row}, \n{col}) rectangle  +({random(2,3)},rand)
node[near start] {\randomarrow};
}
\begin{pgfonlayer}{background}
\draw[orange!70!black,line width=1pt,fill=yellow!15]
(current bounding box.north west)
rectangle
(current bounding box.south east);
\end{pgfonlayer}
\end{tikzpicture}%
}

\begin{document}

\RandArrow

\def\Columns{10}
\RandArrow[80]

\end{document}


-
Just to be sure. Is there any difference between using \pgfmathparse{random()} \pgfmathsetmacro\xpos{\width*\pgfmathresult} or just \width*rnd instead of \xpos? –  Ignasi May 22 '14 at 15:39
@Ignasi since I didn't use any arguments to random(), they should be equivalent. –  Gonzalo Medina May 22 '14 at 15:43
@Ignasi now I edited my answer using arguments for some of the random and now rnd and random(2,3) behave differently. –  Gonzalo Medina May 22 '14 at 15:58
Gonzalo I wanted to be sure because I didn't understand why was so much typping needed ;-) –  Ignasi May 22 '14 at 16:25
Please see the edited question @GonzaloMedina –  subham soni May 22 '14 at 16:25

## Edit: random non crossing arrows

Here is a very simple solution (using a grid placement) with random colors, random lengths and random directions.

\documentclass[tikz]{standalone}
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\begin{document}
\begin{tikzpicture}
\fill[black] (0.5,0.5) rectangle (10.5,10.5);
\foreach \x in {1,...,10} {
\foreach \y in {1,...,10} {
% random HSB color definition
\pgfmathsetmacro\hue{rnd}
\definecolor{mycolor}{rgb:hsb}{\hue,1,1}
% random direction and length
\pgfmathsetmacro\angle{rnd*360}
\pgfmathsetmacro\halflen{rnd*.3+0.2}
% arrow
\draw[line width=2pt,-stealth,color=mycolor]
(\x,\y) +(\angle:-\halflen) -- +(\angle:\halflen);
}
}
\end{tikzpicture}
\end{document}


## First version: random arrows

Here is a possible solution.

The rnd function generates a pseudo-random number between 0 and 1. Thus:

• (rnd*4+3,rnd*4+3) gives a random coordinate between (3,3) and (7,7).
• ++(rnd*360:rnd*2+1) moves the previous coordinate in any direction (rnd*360) with a length between 1cm and 3cm.

The random function used with two arguments x and y generates a random integer between x and y. Thus:

• \pgfmathtruncatemacro\numcolor{random(0,3)} sets \numcolor with a random integer between 0 and 3.

To change the seed used by pseudo-random generator at each compilation, you may use (with pdflatex) \pgfmathsetseed{\pdfuniformdeviate 10000000} in your peamble.

\documentclass[tikz]{standalone}
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\tikzset{
my arrow/.style={-latex,line width=2},
my arrow 0/.style={my arrow,color=red},
my arrow 1/.style={my arrow,color=violet},
my arrow 2/.style={my arrow,color=yellow},
my arrow 3/.style={my arrow,color=black},
}
\begin{document}
\begin{tikzpicture}
\filldraw[color=gray!50] (0,0) rectangle (10,10);
\foreach \num in {1,...,20} {
\pgfmathtruncatemacro\numcolor{random(0,3)}
\draw[my arrow \numcolor] (rnd*4+3,rnd*4+3) -- ++(rnd*360:rnd*2+1);
}
\end{tikzpicture}
\end{document}

-

Random and not grid-aligned arrows, using the code from tikz: Distribute evenly and randomly circles:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\def\xlist{4}
\def\ylist{4}

\newcommand{\fillrandomly}[4]{
\pgfmathsetmacro\diameter{#3*2}
\draw (0-#3,0-#3) rectangle (#1+#3,#2+#3);
\foreach \i in {1,...,#4}{
\pgfmathsetmacro\x{rnd*#1}
\pgfmathsetmacro\y{rnd*#2}
\xdef\collision{0}
\foreach \element [count=\i] in \xlist{
\pgfmathtruncatemacro\j{\i-1}
\pgfmathsetmacro\checkdistance{ sqrt( ({\xlist}[\j]-(\x))^2 + ({\ylist}[\j]-(\y))^2 ) }
\ifdim\checkdistance pt<\diameter pt
\xdef\collision{1}
\breakforeach
\fi
}
\ifnum\collision=0
\xdef\xlist{\xlist,\x}
\xdef\ylist{\ylist,\y}
\pgfmathsetmacro\randomvalue{rnd*360}
\draw [red, line width=4pt, -latex] (\x,\y) +(\randomvalue:-#3) -- +(\randomvalue:#3);
\fi

}
}

\begin{tikzpicture}
\pgfmathsetseed{2}
\fillrandomly{7.5}{5}{0.5}{100}

\end{tikzpicture}
\end{document}

-
Where is the random length? :-) –  kiss my armpit May 22 '14 at 19:01
@MoneyOrientedProgrammer: Adding random length, thickness, colour, arrowhead, curvature, etc. is trivial, so it does not need to be explicitly stated in the answer. –  Jake May 22 '14 at 19:03
Confirmed. Thanks. –  kiss my armpit May 22 '14 at 20:19
+1 for not using a grid. Way more randomish :-) –  Daniel May 23 '14 at 5:35
\documentclass{article}

\begin{document}

\begin{pspicture}(-6,-6)(6,6)
\pstVerb{ realtime srand }% For different output of every run
\psframe[linecolor=black!15](-5,-5)(5,5)
\multido{\iRow=-4+1}{9}{%
\multido{\iCol=-4+1}{9}{%
\rput{!Rand 360 mul}(\iRow,\iCol){%
\pscustom{%
\arrows{->}
\code{Rand Rand Rand setrgbcolor
0 Rand 32 mul dup neg 0 exch ArrowB moveto
lineto Rand 2 mul setlinewidth stroke}}}}}
\end{pspicture}
\end{document}


-
Please see the edited question @Herbert –  subham soni May 22 '14 at 16:26

A try with MetaPost, using its handy uniformdeviate() random function, which generates a random number between 0 and the number specified in argument. The generated vectors are of random-generated origin, direction and length (between 2 cm and 3 cm), they can't be too close to each other thanks to a bb macro which puts a given vector into a "bounding box" and checks with the intersectiontimes function if they don't intersect, and they are of random colors in the RGB specification.

u := 1cm; % unit length
nb_vectors := 20; wd = .5;
boolean intersect; pair random_origin; color random_color; path candidate, random_vector[], bb_candidate, bb[];
%
vardef bb(expr p) =
save orig, extr; pair orig, extr; orig = point 0 of p; extr = point 1 of p;
pair v,w; v = wd*unitvector(extr-orig)*u; w = v rotated 90;
(orig - v + w) -- (extr + v + w) -- (extr + v - w) -- (orig - v - w) -- cycle
enddef;
%
beginfig(1);
pickup pencircle scaled 2bp;
i = 1;
forever:
exitunless (i <=  nb_vectors);
intersect := false;
random_length := u*(2+uniformdeviate(1));
random_angle := uniformdeviate(359);
random_origin := u*(uniformdeviate(wd*nb_vectors), uniformdeviate(wd*nb_vectors));
random_color := (uniformdeviate(1), uniformdeviate(1), uniformdeviate(1));
candidate := random_origin -- (random_origin + random_length*dir(random_angle));
j := 1;
forever:
exitif (j = i) or (intersect = true);
if bb(random_vector[j]) intersectiontimes bb(candidate) <>  (-1, -1):
intersect := true;
fi;
j := j+1;
endfor;
if intersect = false:
random_vector[i] = candidate;
drawarrow candidate withcolor random_color;
i := i+1;
fi;
endfor;
endfig;
end.


Here one of the possible result:

-
I tried to reuse your code for representation of forces but I don't be able to add labels because a conflit with bb[] definition. Did you know a way to fix that? –  Jorge Jan 31 at 16:54
Not sure if it is what you want, but I've got no conflict of any sort if I place freelabel(btex $v$ etex, point .5 of candidate, point .5 of candidate + dir (random_angle + 90)); just after drawarrow candidate withcolor random_color; (the freelabel macro is part of the Metafun format). –  Franck Pastor Jan 31 at 19:48
In Context don't work.! Declared variable conflicts with previous vardef. <to be read again> ; <*> ...idate, random_vector[], bb_candidate, bb[]; –  Jorge Jan 31 at 22:18
I create a new question to [context] guys tex.stackexchange.com/questions/225864/… –  Jorge Jan 31 at 22:39

Modifying the existing PSTricks answer to be more compact, perhaps!

\documentclass[pstricks,border=12pt]{standalone}

\pstVerb
{
realtime srand
/setgray { pop tx@Dict begin Rand Rand Rand end setRGBcolor } def
/Get {8 Rand mul 4 sub} bind def
}

\begin{document}
\begin{pspicture}[arrows=->](-4,-4)(4,4)
\psframe*[linecolor=black!15](-4,-4)(4,4)
\psLoop{100}{\psline(!Get Get)(!Get Get)}
\end{pspicture}
\end{document}


## Animated version

\documentclass[pstricks,border=12pt]{standalone}

\pstVerb
{
realtime srand
/setgray { pop tx@Dict begin Rand Rand Rand end setRGBcolor } def
/Get {8 Rand mul 4 sub} bind def
}

\begin{document}
\psLoop{25}{%
\begin{pspicture}[arrows=->,linewidth=2pt](-4,-4)(4,4)
\psframe*[linecolor=black!15](-4,-4)(4,4)
\psLoop{25}{\psline(!Get Get)(!Get Get)}
\end{pspicture}}
\end{document}


-
Epilepsy warning! –  kiss my armpit May 22 '14 at 16:15
Please see my edited question –  subham soni May 22 '14 at 16:27
@MoneyOrientedProgrammer: How can you stop the arrows from crossing? –  Jake May 22 '14 at 19:04
@Jake: By increasing the frame rate so nobody can see they are actually crossing one over others. :-) –  kiss my armpit May 22 '14 at 19:08