这个问题类似于是否有 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}
更新以获取正确的箭头edge
,loop
但我的代码在某些情况下可能不确定(我需要测试)
\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}