I'm trying to create some TikZ keys which allows to easily draw distributed loads on a mechanical structure (or truss). The code I wrote at the moment is:
\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\makeatletter
\tikzset{load start/.style={insert path={coordinate (mec@start@load)}},%
load end/.style={insert path={coordinate (mec@end@load)}},
load distance/.initial=1em,
force distance/.initial=10pt,
force length/.initial=.7cm}
\tikzset{forze/.code={%
\coordinate (mec@X1) at ($(mec@start@load)!\pgfkeysvalueof{/tikz/load distance}!90:(mec@end@load)$);
\coordinate (mec@X2) at ($(mec@end@load)!\pgfkeysvalueof{/tikz/load distance}!-90:(mec@start@load)$);
\draw (mec@X1) -- (mec@X2);
\pgfpointdiff{\pgfpointanchor{mec@X1}{center}}{\pgfpointanchor{mec@X2}{center}}
\pgfmathsetmacro{\mec@force@distrib@lenght}{veclen(\pgf@x,\pgf@y)}
\pgfmathsetmacro{\mec@force@number}{round(\mec@force@distrib@lenght/\pgfkeysvalueof{/tikz/force distance})}
\pgfmathsetmacro{\mec@force@distance}{1/\mec@force@number}
\pgfmathparse{1-\mec@force@distance}
\foreach \i in {0,\mec@force@distance,...,\pgfmathresult}{
\coordinate (endarrow) at ($(mec@X1)!\i!(mec@X2)$);
\coordinate (startarrow) at ($(endarrow)!\pgfkeysvalueof{/tikz/force length}!90:(mec@X2)$);
\draw[-latex] (startarrow) -- (endarrow);
}
\coordinate (endarrow) at ($(mec@X1)!1!(mec@X2)$);
\coordinate (startarrow) at ($(mec@X2)!\pgfkeysvalueof{/tikz/force length}!-90:(mec@X1)$);
\draw[-latex] (startarrow) -- (endarrow);
}}%}
\makeatother
\begin{document}
\begin{tikzpicture}[node distance=1mm]
\coordinate (a) at (0,0) node[left=of a]{A};
\coordinate (b) at (0,3) node[left=of b]{B};
\coordinate (c) at (3,3) node[right=of c]{C};
\coordinate (d) at (3,0) node[right=of d]{D};
\draw[thick] (a) -- (b) [load start] -- (c) [load end] -- (d);
\path[forze] (a);
\draw (d) [load start] -- (b) [load end];
\path[forze] (a);
\end{tikzpicture}
\begin{tikzpicture}[node distance=1mm]
\coordinate (a1) at (0,0) node[left=of a1]{A1};
\coordinate (b1) at (0,3) node[left=of b1]{B1};
\coordinate (c1) at (3,3) node[right=of c1]{C1};
\coordinate (d1) at (3,0) node[right=of d1]{D1};
\draw[thick] (a1) -- (b1) [load start] -- (c1) [load end,forze] -- (d1);
\draw[forze] (a1) -- (d1);
\end{tikzpicture}
\end{document}
The load start and load end keys are used only to save the beginning and ending coordinates of the distributed load, and the forze key uses these coordinates and draws in the right way the baseline and all of the arrows. In the first example everything works fine but, as you can see, to get the right output it is necessary to define another path (after the one in which load start and load end are used) where the forze key is used.
In the second example I show the syntax I would like to use (basically I want to avoid the necessity to define the second "fake" path) but you can see that something is wrong:
- In the first case the arrows appears, but the specificed path is disappeared (the structure disappears);
- In the second case the path is there (the line from
d1toa1) but the arrows are overimposed to the previous ones.
I think that this happens because the code defined in the forze key is processed too early, when the start and end coordinates of the load are not yet correctly saved.
I tried to use the append after command, execute at end to, execute at end note keys, but the result is always the same. Is there a better approach?
An additional question: is it correct to define macros (like \mec@force@number) via \pgfmathsetmacro within a key (like forze) or it should be better to define them outside it? Which is better from a "register consumption" point of view?
Update
As @percusse suggested, I tried to use the preaction and postaction keys. I tried those possibilities:
\draw[postaction={forze}] (a) -- (b) [load start] -- (c) [load end] -- (d);
Perfect result
\draw[thick,postaction={forze}] (a) -- (b) [load start] -- (c) [load end] -- (d);
% or
\draw[thick][postaction={forze}] (a) -- (b) [load start] -- (c) [load end] -- (d);
% or
\draw[thick][postaction={forze,thin}] (a) -- (b) [load start] -- (c) [load end] -- (d);
bad result: the load appears to be thick too
\draw[preaction={draw,thick},postaction={forze}] (a) -- (b) [load start] -- (c) [load end] -- (d);
perfect result, but not transparent to the user (that should use the preaction key). So it seems that the second time that the path is used, it automatically gets the options from the first one (the manual says that the options are different, but it seems that this is true only if the same options are redefined). Is it possible to avoid this allowing to normally specify options on the path and just use postaction={forze} to draw the load (which can be easily made by a specific key)?
preactionandpostactionoptions to reuse the path more than once. Also related : tex.stackexchange.com/questions/39242/… – percusse Oct 8 '12 at 20:58