Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This question is similar to Is there a TikZ dashed line decorator or some other way to make part of a path dashed?.

What I want to draw: A node with a dashed loop, with a small node on the loop, and the part of the loop from the big node to the small one undashed.

How far I went:

\begin{tikzpicture}[scale=5]
  \draw node (n) [circle,fill] {} edge [dashed,loop above] node
  [fill,circle,minimum size=.4em,inner sep=0pt,pos=0.1] (s) {} ();
  \draw[->] (n) -- (s);
\end{tikzpicture}

The trouble with it being, of course, that the (n)--(s) path does not match the curvy path. The solution of the previous question does not seem to help, as I want to work with a path resulting from a clipping (and I'm not sure to know how).

share|improve this question

1 Answer 1

up vote 11 down vote accepted

This is an incomplete answer or more exactly an answer with some disadvantages. You need to find the length manually of the path between (n) and (s), and if you change the scaling argument, you need to find another length. The main problem is to calculate the length automatically. I think it's possible with the decoration librarybut I don't know enough this library to find a solution. A macro to calculate the length of a path between two nodes would be interesting.

Update of the first code In some simple case, it's possible to calculate the length.

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

\makeatletter
\newif\ifpgfextractpointsreseonmoveto

\pgfextractpointsreseonmovetotrue%
\def\calclength#1{{
    \pgf@decorate@parsesoftpath#1\parsedpath
    \xdef\length{\pgf@decorate@totalpathlength}
    \parsedpath
}} 

\makeatother  
\tikzset{
  solid part/.style={%
  postaction={solid, decorate, draw,ultra thick,
  decoration={
             moveto,
             pre=curveto, 
             post=moveto, 
             pre length=#1,
             post length=#1}}
    }
}    

\begin{document}


\begin{tikzpicture}[scale=2]
   \path[save path=\tmppath] (0,0) -- (6,4); 
    \calclength{\tmppath}   
    \draw[dotted,solid part=.5*\length] (0,0) -- (6,4); 
\end{tikzpicture}   

\begin{tikzpicture}[scale=2]
   \path[save path=\tmppath] (0,0) to[out=0,in=-90] (6,4); 
    \calclength{\tmppath}   
    \draw[dotted,solid part=.5*\length] (0,0) to[out=0,in=-90] (6,4); 
\end{tikzpicture}  
\end{document}    

enter image description here

Update to get the correct arrow with edgeand loop but my code is perhaps not sure in some conditions (I need to test)

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

\makeatletter
\newif\ifpgfextractpointsreseonmoveto

\pgfextractpointsreseonmovetotrue%

\def\pgf@extractprocessorsecond#1{%
 \ifx#1\pgfsyssoftpath@movetotoken
   \ifpgfextractpointsreseonmoveto
     \let\pgf@next=\pgf@extractprocessorfirst%
   \else%
     \let\pgf@next=\pgf@@extractprocessorsecond%
   \fi%
 \else%
   \let\pgf@next=\pgf@@extractprocessorsecond%
 \fi%
 \pgf@next#1%
}

\tikzset{
 adjust arrow/.code={%
   \csname if#1\endcsname%
     \pgfextractpointsreseonmovetofalse%
   \else%
     \pgfextractpointsreseonmovetotrue%
   \fi},
 adjust arrow/.default=true,
}

\makeatother  

\begin{document}

\tikzset{
  solid part/.style={%
  postaction={solid, decorate, draw,adjust arrow,
  decoration={
moveto,
             pre=curveto, 
             post=moveto, 
             pre length=#1,
             post length=#1}}
    }
}

\begin{tikzpicture}[scale=20,>=latex]
   \draw[thick] node (n) [circle,fill] {} 
         edge [<-,dotted,solid part=28mm,loop above] ();
\end{tikzpicture}

\end{document}

enter image description here

Update N°3) The best solution for the moment. I try to use \usetikzlibrary{decorations.markings}but I need to work with to and not edge. To avoid the arrow with loop, I redefine \tikzstyle{every loop}= [shorten >=1pt]

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations} 
\usetikzlibrary{decorations.markings}
\begin{document}

\pgfkeys{
/pgf/decoration/.cd,
pre fraction/.style={pre length=#1*\pgfmetadecoratedpathlength},
post fraction/.style={post length=#1*\pgfmetadecoratedpathlength}
}

\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (4,2);

\draw [  
decoration={ 
curveto,
pre=moveto, pre fraction=0,
post=moveto, post fraction=0.3}, decorate, red, ultra thick] (A) to[out=0,in=-90](B);

\draw [decoration={curveto,
                   pre=moveto, pre fraction=0.7,
                   post=moveto, post fraction=0},%
       decorate, blue, ultra thick,dotted] (A) to[out=0,in=-90](B); 

\path [  
decoration={ 
     markings, mark=at position .7  with {\arrow[red,line width=2pt]{>}}},  
     decorate  ] (A) to[out=0,in=-90](B);         
\end{tikzpicture} 

\begin{tikzpicture}[scale=20,>=latex]  
 \tikzstyle{every loop}= [shorten >=1pt]  
 \node[draw,circle,minimum size=2pt,fill](s){};  
\draw[decoration={curveto,
                  pre=moveto, 
                  pre fraction=0,
                  post=moveto, 
                  post fraction=0.7}, 
      decorate,red, ultra thick] (s)  to[loop above] ();

\draw[decoration={ 
curveto,
pre=moveto, pre fraction=0.33,post=moveto, post fraction=0},
 decorate, blue,dotted, ultra thick] node[]{}  to[loop above] (); 

\path [decoration={markings,
       mark=at position .32  with {\arrow[red,line width=2pt]{>}}},
       decorate  ]  (s)  to [loop above] ();                    
\end{tikzpicture}       
\end{document}

enter image description here

Update final With edge we need to add decorate in the option of `edge``

% remove the arrow from the style of every loop
\tikzset{every loop/.style={looseness=10}}
\begin{tikzpicture}[scale=5] 
% draw the loop
 \draw node (n) [circle,draw] {A} edge [dashed,loop above]   ();  
% first decoration : solid line
\path [ decoration={ curveto,
                     pre=moveto, 
                     pre fraction=0,
                     post=moveto, 
                     post fraction=0.9},red,thick]%
                      (n) edge[decorate,loop above]();  
% second decoration the arrow 
 \path[>=latex,decoration={  markings, 
                     mark=at position .12  with {\arrow[red,thick]{>}}}]%
                      (n) edge[decorate,loop above]  ();

\end{tikzpicture}

enter image description here

share|improve this answer
    
Great! I've been tweaking with that solution for some time now, and, trying to find a shorter solution, I felt back at yours :-) There's still two glitches: how can I get an arrow tip at the end of the solid line, and what is the clean way to avoid the weird double arrow tip at the end of the dotted path? Thanks! –  Michaël Dec 1 '11 at 19:52
    
I need to correct my code. The problem comes from edge. I use this code only with --and tobut you need edge to creta a loop. The code is complicated to avoid the weird double arrow tip at the end of the dotted path and I don't know how to get an arrow at the end of the solid line :( –  Alain Matthes Dec 1 '11 at 22:08
    
@Michaël Be careful with this code because it's not perfect and I need to hack some intern macros and it's not easy –  Alain Matthes Dec 1 '11 at 22:54
    
Still, a quite nice approach. –  percusse Dec 1 '11 at 23:14
    
Thanks @Altermundus ! I'll play with that later on today. Still, I'm being quite frustrated with TikZ. Every time I try to make a simple (IMO) drawing, I end up hacking for hours on :-( –  Michaël Dec 2 '11 at 15:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.