5

The idea was creating decoration that draws half full half dashed vector. Based on percusse's suggestion I wrote the following MWE:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\usetikzlibrary{decorations}

\pgfdeclaredecoration{halfdashed}{initial}{%
\state{initial}[width=0.5*\pgfdecoratedpathlength,next state=final]{%
\pgfpathmoveto{\pgfpoint{0}{0}}%
\pgfpathlineto{\pgfpoint{0.5*\pgfdecoratedpathlength}{0}}%
\pgfusepathqstroke
}%
\state{final}{%
\pgfsetdash{{10pt}{10pt}}{10pt}%
\pgfpathmoveto{\pgfpoint{0}{0}}%
\pgfpathlineto{\pgfpoint{0.5*\pgfdecoratedpathlength}{0}}%
}}

\begin{tikzpicture}
\draw[line width=2pt,decorate,decoration={halfdashed},->] (0,1) -- ++(110pt,0);
\draw[line width=2pt,decorate,decoration={halfdashed},->] (0,0) -- ++(100pt,0);
\end{tikzpicture}

\end{document}

The result is here:

enter image description here

I conclude that \pgfdeclaredecoration uses stroke parameters only at the very end of drawing decoration. How can I get those parameters and put them in front of pgfpathqstroke? BTW, I had to use pgfpathqstroke, because \pgfdeclaredecoration does pass arrow parameter right in the beginning (doh!).

Pygmalion
  • 6,387
  • 4
  • 34
  • 68
  • You could try adding \pgfsetlinewidth{\pgflinewidth} \pgfsetdash{}{0pt} to the first state. Adding color to the line will be trickier. – Mark Wibrow Nov 14 '14 at 17:28
  • @MarkWibrow Great, this solves width and dashing problem. How come this has to be specified manually? – Pygmalion Nov 14 '14 at 18:26
  • I used Mark Wibrow's suggestion to answer my own question here http://tex.stackexchange.com/questions/205149/draw-partially-dashed-vector-using-decoration – Pygmalion Nov 14 '14 at 19:38
  • @MarkWibrow Bugger, there is another problem. Things drawn after halfdashed line are also dashed. It seems that \pgfsetdash{{10pt}{10pt}}{10pt} turns on something that is not easily turned off. – Pygmalion Nov 14 '14 at 20:02
  • There is no need to use a state for the first half. Just use pre=lineto and start in the middle – percusse Nov 14 '14 at 20:45
  • @percusse I hope this is the last from me. I solved the problem by turning the problem around. Default is dashed, and I forced first half into solid. The point is that after messing with defaults in first half, I cleaned up. Maybe you find this idea useful. – Pygmalion Nov 14 '14 at 22:11
  • @MarkWibrow I hope this is the last from me. I solved the problem by turning the problem around. Default is dashed, and I forced first half into solid. The point is that after messing with defaults in first half, I cleaned up. Maybe you find this idea useful. – Pygmalion Nov 14 '14 at 22:12
  • @MarkWibrow Do you know the command which is reverse of \pgfsetlinewidth, i.e. command that returns current linewidth? – Pygmalion Nov 17 '14 at 13:05
  • @Pygmalion There isn't one that I know of. I know the line width has to be manually saved in certain places, but I presume most of time the line width is restored when the current scope ends (either PGF scope or PDF scope). – Mark Wibrow Nov 17 '14 at 15:08

1 Answers1

4

Well turning the idea around works.

So, I draw dashed line and I decorate first half as a full line.

You don't wanna mess with final part of the decoration, because you cannot clean up after you mess up with defaults. But you can mess with the previous part(s) of decoration (\pgfsetlinewidth{\pgflinewidth}), do your stuff, and return to defaults (\pgfsetlinewidth{\tikzscope@linewidth}) before finishing state, and voila!

Disclaimer: I think that \tikzscope@linewidth is default line width outside decoration, but I am not 100% sure.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\usetikzlibrary{decorations}

\makeatletter
\pgfdeclaredecoration{halffull}{initial}{%
\state{initial}[width=0.5*\pgfdecoratedpathlength,next state=final]{%
\pgfsetlinewidth{\pgflinewidth}
\pgfpathmoveto{\pgfpoint{0}{0}}
\pgfpathlineto{\pgfpoint{0.5*\pgfdecoratedpathlength}{0}}
\pgfusepathqstroke
\pgfsetlinewidth{\tikzscope@linewidth}}
\state{final}{%
\pgfpathmoveto{\pgfpoint{0}{0}}
\pgfpathlineto{\pgfpoint{0.5*\pgfdecoratedpathlength}{0}}}}
\makeatother

\begin{tikzpicture}
\draw[ultra thick,dashed,dash phase=3pt,decorate,decoration=halffull,->] (-2,0) -- (2,0);
\draw[very thin] (0,-1) -- (0,1);
\end{tikzpicture}

\end{document}

enter image description here

Pygmalion
  • 6,387
  • 4
  • 34
  • 68
  • Many of the parameters that are set using keys in a TikZ path are "saved" until the path specification is finished and then applied (if you are really interested, look at the definition of \tikz@finish in tikz.code.tex). Decorations are among the first to be applied followed by things like drawing, filling and so on. By using the path inside a decoration state whatever parameters have been set (i.e., passed down through the PGF basic layer) will be applied, the rest will be applied to the path that is left when the decoration is finished. – Mark Wibrow Nov 14 '14 at 22:13
  • @MarkWibrow Hmm, that means I didn't clean up properly! I should somehow get and save "current" line width before \pgfsetlinewidth{\pgflinewidth} ("current" line width is default width outside decoration and it differs from \pgflinewidth!!!). Then after \pgfusepathqstroke I should return to "current" line width and not to 0.4pt. – Pygmalion Nov 14 '14 at 22:21