Res: dotted decoration
Flavio Costa <flaviocosta <at> yahoo.com.br>
2008-06-03 18:09:43 GMT
Hi Mark,
Thank you for your reply and your effort. I supposed that maybe there would be a cleaner way, like creating a
new decoration similar to "ticks", but rotated accordingly. Now I see that the arrow tips do not interact
very well with subpaths and with most decoration types. I replaced snakes for ticks but it didn't work
correctly, it seems only path morphing decorations give the desired result.
Your "dash middle" or "solid ends" are interesting, but I'm going to need this effect only once and it does
not justify using all this code just for it. Therefore, I had to adopt the "poor man's solid ends":
\draw[<-,thick] (0,3.5) -- +(4em,0);
\draw[loosely dotted,thick] (4em,3.5) -- +(10.125em,0);
\draw[->,thick] (14.125em,3.5) -- +(4em,0);
Best regards,
Flavio
----- Mensagem original ----
De: Mark Wibrow <m.wibrow <at> googlemail.com>
Para: Flavio Costa <flaviocosta <at> yahoo.com.br>
Cc: TikZ & PGF Mailing List <pgf-users <at> lists.sourceforge.net>
Enviadas: Terça-feira, 3 de Junho de 2008 7:07:46
Assunto: Re: [Pgf-users] dotted decoration
Hi!
Unfortunately there does not seem (to me) to be a straightforward
general solution to this (i.e., that works in the majority of
situations imaginable). The problems involve how decorations work,
and how arrows are placed on processed softpaths.
It might be possible to define a (meta-)decoration which would do the
job, but getting it to integrate cleanly with tikz keys like `loosely
dashed' and the way arrowheads are specified would be messy (maybe
even impossible).
However, with some minimal hacking of the basic layer (shown below)
something approaching a `decent' solution can be acheived. The hacking
is necessitated by the fact that considering:
\tikz\draw [<->] (0,0) -- (1,1) (2,2) -- (3,3);
the arrows are drawn on the second subpath. The hacked version allows
the arrows to be drawn at the start and end of the entire path.
\tikz\draw [<->, start arrow on first subpath] (0,0) -- (1,1) (2,2) -- (3,3);
The special curveto is required because the first (very tiny) straight
line drawn by the curveto decoration is too small to make the
arrowhead point correctly, so the decoration curveto* gets around this
with an initial state width equivalent to the line width. All of the
above allows the 4em pre and post decorations to have arrows
positioned correctly.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
\begin{document}
% Look away now if you don't like hacking...
%
\makeatletter
\newif\ifpgfextractpointsreseonmoveto
\pgfextractpointsreseonmovetotrue%
% Minor hack of the \pgfprocesspathextractpoints process.
%
\def\pgf <at> extractprocessorsecond#1{%
\ifx#1\pgfsyssoftpath <at> movetotoken%
\ifpgfextractpointsreseonmoveto%
% Reset things...
\let\pgf <at> next=\pgf <at> extractprocessorfirst%
\else%
\let\pgf <at> next=\pgf <at> <at> extractprocessorsecond%
\fi%
\else%
\let\pgf <at> next=\pgf <at> <at> extractprocessorsecond%
\fi%
\pgf <at> next#1%
}
\def\pgf <at> extractprocessorother#1{%
\ifx#1\pgfsyssoftpath <at> movetotoken%
\ifpgfextractpointsreseonmoveto%
% Reset things...
\let\pgf <at> next=\pgf <at> extractprocessorfirst%
\else%
\let\pgf <at> next=\pgf <at> <at> extractprocessorother%
\fi%
\else%
\let\pgf <at> next=\pgf <at> <at> extractprocessorother%
\fi%
\pgf <at> next#1%
}
% Minor hack of the \pgfprocesspathreplacestartandend process.
%
\def\pgf <at> replaceprocessother#1{%
\ifx#1\pgfsyssoftpath <at> movetotoken%
\ifpgfextractpointsreseonmoveto%
\pgf <at> replace <at> handle <at> move%
\fi%
\fi%
\pgf <at> <at> next#1%
}
\tikzset{
start arrow on first subpath/.code={% <- Not a very good name.
\csname if#1\endcsname%
\pgfextractpointsreseonmovetofalse%
\else%
\pgfextractpointsreseonmovetotrue%
\fi},
start arrow on first subpath/.default=true,
}
\makeatother% ...and now back to business.
% We must make a special curveto
%
\pgfdeclaredecoration{curveto*}{initial}{
\state{initial}[width=\pgflinewidth, next state=curveto]
{
\pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}}
}
\state{curveto}[width=\pgfdecoratedinputsegmentlength/100]
{
\pgfpathlineto{\pgfpointorigin}
}
\state{final}{\pgfpathlineto{\pgfpointdecoratedpathlast}}
}
\tikzset{
dash middle/.style={%
postaction={solid, decorate, start arrow on first subpath, draw,
decoration={moveto, pre=curveto*, post=curveto*, pre length=#1,
post length=#1}
},
postaction={decorate, draw, -,
decoration={curveto, pre=moveto, post=moveto, pre length=#1, post length=#1}
}
}
}
\tikz\draw[<->, loosely dashed, dash middle=4em, very thick] (0,3) --
+(18.125em,0);
\tikz\path[<->, loosely dotted, dash middle=4em, very thick] (0,0) ..
controls (0,2) and (3,0) .. (3,2);
\end{document}
Hope this helps.
Mark
Abra sua conta no Yahoo! Mail, o único sem limite de espaço para armazenamento!
http://br.mail.yahoo.com/
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/