重复使用路径的一部分

重复使用路径的一部分

这个问题类似于是否有 TikZ 虚线装饰器或其他方法可以使路径的一部分变为虚线?

我想要绘制的内容:带有虚线环的节点,带有小节点环路,以及环路中从大节点到小节点的部分不虚线。

我走了多远:

\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}

当然,问题在于路径与(n)--(s)曲线路径不匹配。上一个问题的解决方案似乎没有帮助,因为我想处理由剪切产生的路径(但我不确定该怎么做)。

答案1

这是一个不完整的答案,或者更确切地说是一个有一些缺点的答案。您需要手动找到(n)和之间的路径长度(s),并且如果您更改缩放参数,则需要找到另一个长度。主要问题是自动计算长度。我认为使用是可能的,decoration library但我对这个库了解不够多,无法找到解决方案。计算两个节点之间路径长度的宏会很有趣。

第一个代码的更新在某些简单的情况下,可以计算长度。

\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}    

在此处输入图片描述

更新以获取正确的箭头edgeloop但我的代码在某些情况下可能不确定(我需要测试)

\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}

在此处输入图片描述

更新 N°3)目前最好的解决方案。我尝试使用,\usetikzlibrary{decorations.markings}但我需要使用to而不是edge。为了避免使用箭头loop,我重新定义了\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}

在此处输入图片描述

更新最终版本edge我们需要添加 decorate“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}

在此处输入图片描述

相关内容