这就是我想要得到的,T 型路口所有可能转弯的图形表示:
这就是我所拥有的:
我当前的图表看起来不太好看:
- 弧线很奇怪,不好看也不圆
- 我的箭头位于弧的端点,而示例中的箭头偏离中心,并且具有不同的样式
关于如何完成这些并整理我的图表有什么建议吗(我确实想保留顶点中的字母)?这是生成我当前图表的代码:
\usetikzlibrary{shapes,arrows,shapes.multipart,positioning, fit, calc}
...
\begin{tikzpicture}
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\begin{scope}[every edge/.style={draw=lightgray,line width=3pt}]
\path [-] (A) edge (B);
\path [-] (B) edge (C);
\path [-] (B) edge (D);
\end{scope}
%line graph
\begin{scope}[every node/.style={circle,thick,draw,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5,.5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5,.5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[every edge/.style={draw=black,line width=1pt}]
\path [->] (AB) edge (BC);
\path [->] (CB) edge (BA);
\path [->] (AB) edge[out=0,in=0] (BA);
\path [->] (BA) edge[out=180,in=180] (AB);
\path [->] (BC) edge[out=0,in=0] (CB);
\path [->] (CB) edge[out=180,in=180] (BC);
\path [->] (AB) edge[out=0,in=-90] (BD);
\path [->] (DB) edge[out=270,in=180] (BC);
\path [->] (BD) edge[out=90,in=90] (DB);
\path [->] (DB) edge[out=270,in=270] (BD);
\path [->] (CB) edge[out=180,in=270] (BD);
\path [->] (DB) edge[out=270,in=0] (BA);
% \path [-] (B) edge (D);
\end{scope}
\end{tikzpicture}
========更新==========
使用下面@Zarko 的建议,我最终得到了以下简洁的结果: 产生此结果的代码:
\begin{tikzpicture}[scale=0.9,
DL/.style args = {#1/#2}{% Decorate Loop, #1: position, #2:adjust tangent
decoration={markings,
mark=at position #1 with {\draw[-Stealth] (-1pt,#2) -- (1pt,-#2);}},
postaction={decorate}
},
DL/.default = 0.53/0.15pt
]
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\draw[lightgray,line width=3pt] (A) -- (B)
(B) -- (C)
(B) -- (D);
%line graph
\begin{scope}[every node/.style={circle,draw,thick,scale=.7}]
\node (AB) at (1,-.5) {};
\node (BA) at (1, .5) {};
\node (BC) at (5,-.5) {};
\node (CB) at (5, .5) {};
\node (BD) at (3.5,2) {};
\node (DB) at (2.5,2) {};
\end{scope}
\begin{scope}[every edge/.style={draw,line width=1pt}]
\path (AB) edge[DL=0.36/0.00pt] (BC)
(CB) edge[DL=0.7/0.00pt] (BA);
%U-turns:
\begin{scope}[every edge/.append style={DL, bend right=75, looseness=1.4}]
\path (AB) edge (BA)
(BA) edge (AB)
(BC) edge (CB)
(CB) edge (BC)
(BD) edge (DB)
(DB) edge (BD);
\end{scope}
\begin{scope}[every edge/.append style={bend right=45, looseness=.85}]
\path (AB) edge[DL=0.8/0.05pt] (BD)
(DB) edge[DL=0.7/0.08pt] (BC);
\end{scope}
\begin{scope}[every edge/.append style={bend left=45, looseness=1}]
\path (DB) edge[DL=0.53/0.00pt] (BA)
(CB) edge[DL=0.53/0.00pt] (BD);
\end{scope}
\end{scope}
\end{tikzpicture}
答案1
使用tikz
库arrows.meta
并decorations.markings
在选定位置上绘制几乎等于切线(手动可调)的箭头。结果并不完美,但接近完美。此奖励是相对较短的代码:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows, % not used in this mwe
arrows.meta, % added
calc, % not used in this mwe
decorations.markings, % added
fit, % not used in this mwe
positioning, % not used in this mwe
shapes, shapes.multipart % not used in this mwe
}
\begin{document}
\begin{tikzpicture}[
DL/.style args = {#1/#2}{% Decorate Loop, #1: position, #2:adjust tangent
decoration={markings,
mark=at position #1 with {\draw[-Stealth] (-1pt,#2) -- (0,0);}},
postaction={decorate}
},
DL/.default = 0.55/0.2pt
]
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\draw[lightgray,line width=3pt] (A) -- (B)
(B) -- (C)
(B) -- (D);
%line graph
\begin{scope}[every node/.style={circle,draw,thick,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5, .5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5, .5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[every edge/.style={draw,line width=1pt}]
\path (AB) edge[DL=0.53/0pt] (BC)
(CB) edge[DL=0.53/0pt] (BA);
\begin{scope}[every edge/.append style={DL, bend right=75, looseness=1.4}]
\path (AB) edge (BA)
(BA) edge (AB)
(BC) edge (CB)
(CB) edge (BC)
(BD) edge (DB)
(DB) edge (BD);
\end{scope}
\begin{scope}[every edge/.append style={bend right=45, looseness=1}]
\path (BA) edge[DL=0.53/0.12pt] (DB)
(BD) edge[DL=0.53/0.12pt] (CB)
(AB) edge[DL=0.8/0.05pt] (BD)
(DB) edge[DL=0.7/0.08pt] (BC);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
编辑: 添加了缺失的箭头,更好地定位它们
答案2
我认为加载arrows.meta
和bending
库会对您有益。更新:我无法抗拒创造一种风格,允许人们把弯曲路径上任意位置的箭头。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc} % shapes,arrows,shapes.multipart,positioning, fit, were not used
\usetikzlibrary{arrows.meta,bending,decorations.markings,intersections} %< added
\tikzset{% inspired by https://tex.stackexchange.com/a/316050/121799
arc arrow/.style args={%
to pos #1 with length #2}{
decoration={
markings,
mark=at position 0 with {\pgfextra{%
\pgfmathsetmacro{\tmpArrowTime}{#2/(\pgfdecoratedpathlength)}
\xdef\tmpArrowTime{\tmpArrowTime}}},
mark=at position {#1-\tmpArrowTime} with {\coordinate(@1);},
mark=at position {#1-2*\tmpArrowTime/3} with {\coordinate(@2);},
mark=at position {#1-\tmpArrowTime/3} with {\coordinate(@3);},
mark=at position {#1} with {\coordinate(@4);
\draw[-{Stealth[length=#2,bend]}]
(@1) .. controls (@2) and (@3) .. (@4);},
},
postaction=decorate,
}
}
\begin{document}
\begin{tikzpicture}
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\begin{scope}[every edge/.style={draw=lightgray,line width=3pt}]
\path [-] (A) edge (B);
\path [-] (B) edge (C);
\path [-] (B) edge (D);
\end{scope}
%line graph
\begin{scope}[every node/.style={circle,thick,draw,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5,.5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5,.5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[line width=1pt]
% bottom left
\draw[arc arrow=to pos 0.55 with length 3mm] (AB) to[out=0,in=0,looseness=1.25] (BA);
\draw[arc arrow=to pos 0.55 with length 3mm] (BA) to[out=180,in=-180,looseness=1.25] (AB);
% bottom right
\draw[arc arrow=to pos 0.55 with length 3mm] (BC) to[out=0,in=0,looseness=1.25] (CB);
\draw[arc arrow=to pos 0.55 with length 3mm] (CB) to[out=180,in=-180,looseness=1.25] (BC);
% middle top
\draw[arc arrow=to pos 0.55 with length 3mm] (BD) to[out=90,in=90,looseness=1.25] (DB);
\draw[arc arrow=to pos 0.55 with length 3mm] (DB) to[out=-90,in=-90,looseness=1.25] (BD);
% straight arrows
\draw[postaction={decorate},decoration={markings,
mark=at position 0.45 with {\arrow{Stealth[length=3mm]}}}] (AB) -- (BC);
\draw[postaction={decorate},decoration={markings,
mark=at position 0.45 with {\arrow{Stealth[length=3mm]}}}] (CB) -- (BA);
% upper arcs
\draw[arc arrow=to pos 0.55 with length 3mm] (CB) to[out=180,in=-90,looseness=1.25] (BD);
\draw[arc arrow=to pos 0.55 with length 3mm] (DB) to[out=270,in=0,looseness=1.25] (BA);
% lower right arc
\draw[arc arrow=to pos 0.35 with length 3mm] (DB)
to[out=-90,in=120,looseness=1.25] ($(B.east)+(3mm,0)$)
to[out=-60,in=180,looseness=1.25] (BC);
\draw[arc arrow=to pos 0.85 with length 3mm] (AB)
to[out=0,in=-120,looseness=1.25] ($(B.west)+(-3mm,0)$)
to[out=60,in=-90,looseness=1.25] (BD);
\end{scope}
\end{tikzpicture}
\end{document}
我保留了原始解决方案以供比较。是的,你可以将上图中的圆弧变成真正的圆弧或椭圆弧。你只需要下面的路径构造。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc} % shapes,arrows,shapes.multipart,positioning, fit, were not used
\usetikzlibrary{arrows.meta,bending} %< added
\begin{document}
\begin{tikzpicture}
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\begin{scope}[every edge/.style={draw=lightgray,line width=3pt}]
\path [-] (A) edge (B);
\path [-] (B) edge (C);
\path [-] (B) edge (D);
\end{scope}
%line graph
\begin{scope}[every node/.style={circle,thick,draw,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5,.5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5,.5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[line width=1pt]
% bottom left
\draw let \p1=($(AB)-(BA)$) in (AB) arc(-90:90:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(AB)-(BA)$) in (AB) arc(-90:0:{veclen(\x1,\y1)/2});
\draw let \p1=($(BA)-(AB)$) in (BA) arc(90:270:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(AB)-(BA)$) in (BA) arc(90:180:{veclen(\x1,\y1)/2});
% bottom right
\draw let \p1=($(BC)-(CB)$) in (BC) arc(-90:90:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(BC)-(CB)$) in (BC) arc(-90:0:{veclen(\x1,\y1)/2});
\draw let \p1=($(CB)-(BC)$) in (CB) arc(90:270:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(BC)-(CB)$) in (CB) arc(90:180:{veclen(\x1,\y1)/2});
% middle top
\draw let \p1=($(BD)-(DB)$) in (BD) arc(00:180:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(BD)-(DB)$) in (BD) arc(00:90:{veclen(\x1,\y1)/2});
\draw let \p1=($(DB)-(BD)$) in (DB) arc(-180:0:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]}] let \p1=($(BD)-(DB)$) in (DB) arc(180:270:{veclen(\x1,\y1)/2});
% straight arrows
\draw[-{Stealth[length=3mm]}] let \p1=($(AB)-(BC)$) in (AB) --
++({veclen(\x1,\y1)/2},0);
\draw (AB) -- (BC);
\draw[-{Stealth[length=3mm]}] let \p1=($(CB)-(BA)$) in (CB) --
++(-{veclen(\x1,\y1)/2},0);
\draw (CB) -- (BA);
% upper right arc
\draw[-{Stealth[length=3mm]}] let \p1=($(CB)-(BD)$) in (CB)
arc(270:210:{veclen(\x1,\y1)/sqrt(2)});
\draw let \p1=($(CB)-(BD)$) in (CB)
arc(270:180:{veclen(\x1,\y1)/sqrt(2)});
% upper left arc
\draw[-{Stealth[length=3mm]}] let \p1=($(BA)-(DB)$) in (DB)
arc(00:-60:{veclen(\x1,\y1)/sqrt(2)});
\draw let \p1=($(BA)-(DB)$) in (DB)
arc(00:-90:{veclen(\x1,\y1)/sqrt(2)});
% lower right arc
\draw[-{Stealth[length=3mm]}] let \p1=($(BC)-(BD)$) in (BC)
arc(270:210:{abs(\x1) and abs(\y1)});
\draw let \p1=($(BC)-(BD)$) in (BC)
arc(270:180:{abs(\x1) and abs(\y1)});
% lower left arc
\draw[-{Stealth[length=3mm]}] let \p1=($(AB)-(DB)$) in (DB)
arc(00:-45:{abs(\x1) and abs(\y1)});
\draw let \p1=($(AB)-(DB)$) in (DB)
arc(00:-90:{abs(\x1) and abs(\y1)});
\end{scope}
% unfortunately we need to refill the circles
% alternatively we could have worked with west, east etc. but that's more
% effort and also would distort the circles of the arrows
\foreach \X in {AB,BA,BC,CB,BD,DB}
{\fill[white] (\X) circle (1mm);}
\end{tikzpicture}
\end{document}
代码看起来很长(好吧,确实很长 ;-) 但它只是一个构建块的复制和粘贴。可以为此编写一个宏...
编辑:修正了左弧的方向。
评论:是的,我知道这个decoration.markings
库,它能够将箭头(或其他任何东西)放在路径上我想要的位置。我在这里没有使用它的原因是我不知道如何根据底层路径弯曲这些箭头,所以我只需要画两条路径。
更新:我刚刚意识到两条弧线并不像你想要的那样。我利用这个机会编写了一个半智能宏来绘制圆弧和椭圆弧。(它是半智能的,所以你当然可以欺骗它,但至少在这些例子中它完成了它的工作。)我不能将它用于之前不正确的弧线,因为它们会穿过节点B
,在我看来这看起来很丑陋。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc} % shapes,arrows,shapes.multipart,positioning, fit, were not used
\usetikzlibrary{arrows.meta,bending,decorations.markings,intersections} %< added
\newcommand{\DrawArcWithBentArrow}[6][]{%
% #1 option(s)
% #2 start, #3 end, #4 start angle, #5 end angle, #6 angle of arrow position
\pgfmathtruncatemacro{\AngSum}{mod(#4+#5,180)}
\ifnum\AngSum=0
\draw[#1] let \p1=($(#2)-(#3)$) in (#2) arc(#4:#5:{veclen(\x1,\y1)/2});
\draw[-{Stealth[length=3mm,bend]},#1] let \p1=($(#2)-(#3)$) in (#2)
arc(#4:#6:{veclen(\x1,\y1)/2});
\else
\begin{pgfinterruptboundingbox} % make sure the auxiliary paths don't mess up bbox
\path let \p1=($(#2)-(#3)$), \n1 = {veclen(\x1,\y1)/2} in
\pgfextra{\xdef\ArrDist{\n1}};
\path[name path=aux1] ($(#2)+(#4:{-2*\ArrDist})$) -- ($(#2)+(#4:{2*\ArrDist})$);
\path[red,name path=aux2] ($(#3)+(#5:{-2*\ArrDist})$) -- ($(#3)+(#5:{2*\ArrDist})$);
\path[name intersections={of=aux1 and aux2, by=aux3},red]
let \p1 = ($(aux3)-(#2)$), \p2 = ($(aux3)-(#3)$), \n1 = {veclen(\x1,\y1)},
\n2 = {veclen(\x2,\y2)} in
\pgfextra{\xdef\ArrDistA{\n1}\xdef\ArrDistB{\n2}}
arc(#4:#5:{(abs(veclen(\x1,\y1))} and {abs(veclen(\x2,\y2))});
\end{pgfinterruptboundingbox}
\draw[#1] (#2) arc(#4:#5:{\ArrDistA} and {\ArrDistB});
\draw[-{Stealth[length=3mm,bend]},#1] (#2) arc(#4:#6:{\ArrDistA} and {\ArrDistB});
\fi
}
\begin{document}
\begin{tikzpicture}
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\begin{scope}[every edge/.style={draw=lightgray,line width=3pt}]
\path [-] (A) edge (B);
\path [-] (B) edge (C);
\path [-] (B) edge (D);
\end{scope}
%line graph
\begin{scope}[every node/.style={circle,thick,draw,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5,.5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5,.5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[line width=1pt]
% bottom left
\DrawArcWithBentArrow{AB}{BA}{-90}{90}{0}
\DrawArcWithBentArrow{BA}{AB}{90}{270}{180}
% bottom right
\DrawArcWithBentArrow{BC}{CB}{-90}{90}{0}
\DrawArcWithBentArrow{CB}{BC}{90}{270}{180}
% middle top
\DrawArcWithBentArrow{BD}{DB}{0}{180}{90}
\DrawArcWithBentArrow{DB}{BD}{180}{360}{270}
% straight arrows
\draw[postaction={decorate},decoration={markings,
mark=at position 0.45 with {\arrow{Stealth[length=3mm]}}}] (AB) -- (BC);
\draw[postaction={decorate},decoration={markings,
mark=at position 0.45 with {\arrow{Stealth[length=3mm]}}}] (CB) -- (BA);
% upper right arc
\DrawArcWithBentArrow{CB}{BD}{270}{180}{210}
% upper left arc
\DrawArcWithBentArrow{DB}{BA}{0}{-90}{-60}
% lower right arc
\draw (DB) to[out=-90,in=120] ($(B.east)+(3mm,0)$)
to[out=-60,in=180] (BC);
\draw[-{Stealth[length=3mm]}] (DB) to[out=-90,in=120] ($(B.east)+(3mm,0)$);
% lower left arc
\draw (AB) to[out=00,in=-120] ($(B.west)+(-3mm,0)$)
to[out=60,in=-90] (BD);
\draw[-{Stealth[length=3mm]}] (AB) to[out=00,in=-120] ($(B.west)+(-3mm,0)$);
\end{scope}
% unfortunately we need to refill the circles
% alternatively we could have worked with west, east etc. but that's more
% effort and also would distort the circular shape of the arrows
\foreach \X in {AB,BA,BC,CB,BD,DB}
{\fill[white] (\X) circle (1mm);}
\end{tikzpicture}
\end{document}
答案3
我认为没有命令可以绘制圆形箭头。至少我在手册中没有找到它。但是如果你在正确的条件下在两个点之间绘制一条边,它应该是一条圆弧(大的已经是圆形的了)。在下面我部分解决了你的问题,剩下的就交给你了,因为我有点困了。
我解决了中间箭头的问题。在中间插入另一个节点就足够了。你只需要添加另一个中间节点在大弧线中。
就圆弧而言,我的圆弧并不完全是圆形的,但如果你稍微移动一下_mid_node_(你应该将它移动的长度等于表示节点的圆的半径)。
代码:
\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,shapes.multipart,positioning, fit, calc}
\begin{document}
\begin{tikzpicture}
%roads: grey graph
\begin{scope}[every node/.style={circle,thick,draw}]
\node (A) at (0,0) {A};
\node (B) at (3,0) {B};
\node (C) at (6,0) {C};
\node (D) at (3,3) {D};
\end{scope}
\begin{scope}[every edge/.style={draw=lightgray,line width=3pt}]
\path [-] (A) edge (B);
\path [-] (B) edge (C);
\path [-] (B) edge (D);
\end{scope}
%line graph
\begin{scope}[every node/.style={circle,thick,draw,scale=.7}]
\node (AB) at (1.5,-.5) {};
\node (BA) at (1.5,.5) {};
\node (BC) at (4.5,-.5) {};
\node (CB) at (4.5,.5) {};
\node (BD) at (3.5,1.5) {};
\node (DB) at (2.5,1.5) {};
\end{scope}
\begin{scope}[every edge/.style={draw=black,line width=1pt}]
\path [->] (AB) edge (3,-.5);
\path [-] (3,-.5) edge (BC);
\path [->] (CB) edge (3,.5);
\path [-] (3,.5) edge (BA);
\path [->] (AB) edge[out=0,in=-90] (2,0);
\path [-] (2,0) edge[out=90,in=0] (BA);
\path [->] (BA) edge[out=180,in=90] (1,0);
\path [-] (1,0) edge[out=-90,in=180] (AB);
\path [->] (BC) edge[out=0,in=-90] (5,0);
\path [-] (5,0) edge[out=90,in=0] (CB);
\path [->] (CB) edge[out=180,in=90] (4,0);
\path [-] (4,0) edge[out=-90,in=180] (BC);
\path [->] (AB) edge[out=0,in=-90] (BD);
\path [->] (DB) edge[out=270,in=180] (BC);
\path [->] (BD) edge[out=90,in=0] (3,2);
\path [-] (3,2) edge[out=180,in=90] (DB);
\path [->] (DB) edge[out=270,in=180] (3,1);
\path [-] (3,1) edge[out=0,in=270] (BD);
\path [->] (CB) edge[out=180,in=270] (BD);
\path [->] (DB) edge[out=270,in=0] (BA);
% \path [-] (B) edge (D);
\end{scope}
\end{tikzpicture}
\end{document}
编辑:你也可以看看在节点之间绘制圆形箭头。