I am trying to decorate a path using random steps and direction, and also draw normal arrows on each segment.
I am facing multiple problems:
- The random part alone works well, but in order to draw the arrows I need to reposition the starting point, which has to be on the segment, and I am not able to determine the location where the last segment ended; I tried to get its coordinates with
\pgfgetlastxy, but they seem to be limited to the state scope, and reset to 0 when a new state is entered (even if the same state is repeated). Using this command at the beginning of the state instead of the end does not help. I hence obtain a "broken" path. - The normal vector do not look normal (except the second); however the two arrows are on the same line, pointing to opposite directions, as expected. I do not understand the reason: is it a machine precision problem? Can it be solved?
- The options of the
drawcommand (red,thickit this case) are only applied to the last segment.
Here is the code I used (the \newcommand at line 6 is used to have the same random angle three times in the state instead of three different random angles), and the relative output.
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,positioning,calc,arrows}
\pgfdeclaredecoration{irregularArrows}{start}{
\newcommand{\SetAngle}{\pgfmathsetmacro{\Angle}{\pgfmathresult * \pgfdecorationsegmentangle}}
\pgfmathsetmacro{\Startx}{\pgfdecorationsegmentlength}
\pgfmathsetmacro{\Starty}{0}
\state{start}[width=\pgfdecorationsegmentlength]{
\pgfmathrand{}
\SetAngle{}
\pgfmathsetmacro{\Startx}{\Startx - \pgfdecorationsegmentlength}
\pgfsetarrowsend{>}
\pgfpathmoveto{\pgfpoint{\Startx}{\Starty}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\Startx}{\Starty}}{\pgfpointpolar{\Angle + 90}{6}}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{\Startx}{\Starty}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\Startx}{\Starty}}{\pgfpointpolar{\Angle - 90}{6}}}
\pgfusepath{stroke}
\pgfpathmoveto{\pgfpoint{\Startx}{\Starty}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\Startx}{\Starty}}{\pgfpointpolar{\Angle}{random * \pgfdecorationsegmentlength}}}
\pgfgetlastxy{\Startx}{\Starty}
}
\state{final}{
\pgfpathlineto{\pgfpointdecoratedpathlast}
}
}
\tikzset{
boundaryArrows/.style={decoration={irregularArrows, segment length = 3cm, angle = 30},
decorate,
},
}
\begin{document}
\pgfmathsetseed{3}
\begin{tikzpicture}
\node[coordinate] (left) at (-10cm, 0) {};
\node[coordinate] (right) at (10cm, 0) {};
\draw[red,thick]{decorate[boundaryArrows]{(left) -- (right)}};
\end{tikzpicture}
\end{document}
The code above aims at being minimal; however, in the unlikely event of my actual problem being simpler, I also include it: what I need is only one pair of arrows (which I am able to achieve using more states), positioned at about the middle of the segment (which I believe I will be able to determine once I understand hot to get the coordinates of the starting point).


Stealthat line 7, and I can move them inside the segment changing the angles from 90 to something else.However you did not modify the decoration, so my plan of getting just one arrow for the whole path using more states do not apply, and I need an alternative for that. I also still do not understand why the
red,thickoptions are ignored. – user408672 May 07 '20 at 10:09\pgfmathsetmacro{\Startx}{\Startx - \pgfdecorationsegmentlength}. At the same time, the decoration puts you in local coordinate systems so that\pgfgetlastxy{\Startx}{\Starty}won't give you the coordinates you probably want. You can define coordinates like\pgfcoordinate{irregularArrowslast}{\pgfpoint{0pt}{0pt}}... – May 07 '20 at 13:32\pgfpathmoveto{\pgfpointanchor{irregularArrowslast}{center}}. I played tiny bit with your code but unfortunately I am completely lost, cannot tell how lines in your code relate to what you want to achieve, and I am not even sure I understand what you want to achieve. However, as for your question why the color behaves the way it does: this is because of the\pgfusepath{stroke}commands you place which get execute before the stroke color gets set. – May 07 '20 at 13:35Stealthat line 7); (2) I want the arrows to be placed in the middle of the segment (also easy, change 90 with something else at lines 9-10) (3) I actually want only one pair of arrows, say in the second line. I know how to do that modifying the decoration (provided that I manage to correctly draw the arrows once), but I do not know if it is possible in your example. (4) I want to be able to colour the path – user408672 May 07 '20 at 14:29
– user408672 May 07 '20 at 14:37\pgfgetlastxy{\Startx}{\Starty}won't give ma the coordinates I want, because the coordinates in the next state add\pgfdecorationsegmentlengthto the x axis transformation. That is why I compute\pgfmathsetmacro{\Startx}{\Startx - \pgfdecorationsegmentlength}\pgfcoordinate{irregularArrowslast}{\pgfpoint{0pt}{0pt}}, and then access it in the next step, see e.g. here. BTW< I am not sure if it is very easy/beneficial to attach one pair of arrows per such a decoration. At least the line joins of the main path will look awful because you interrupt the path. – May 07 '20 at 14:41\Startx,\Startyalways seem to be reset to 0 – user408672 May 07 '20 at 16:08\xdef\Startx{\Startx}\xdef\Starty{\Starty}after\pgfgetlastxy{\Startx}{\Starty}will help you but I do not see how this approach will give you what you want. At the very least the line joins will be bad, if not worse. – May 07 '20 at 16:11