
如果可能第一個 if 轉到第二個輸出而不與其他行重疊,如何更改程式碼,使其不會像圖片中那樣重疊。其次,是否有另一種可能性在 if 部分內建立新行。
感謝您的支持。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes}
\begin{document}
\begin{tikzpicture}[node distance = 1.2cm, auto]
\tikzstyle{startstop} = [rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30]
\tikzstyle{io} = [trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30]
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30]
\tikzstyle{decision} = [diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30]
\tikzstyle{arrow} = [thick,->,>=stealth]
% Place nodes
\node (start) [startstop] {Start};
\node (in1) [io, below of=start] {Input: f(), a, b, $\varepsilon$};
\node (pro1) [process, below of=in1] {c=(a+b)/2};
\node (if1) [decision, below of=pro1, yshift=-1.5cm] {if: f(a)*f(b)$>$0};
% \node (pro1) [process, below of=in1] {Process 1};
\node (dec1) [decision, below of=if1, yshift=-4cm] {While: f(c) $\not=$ 0 \& $|$f(b) - f(a)$|$ $> \delta$};
\node (pro1a) [process, below of=dec1, yshift=-3cm] {c=(a+b)/2};
\node (dec2) [decision, below of=pro1a,yshift=-1.75cm] {if: f(a)*f(c) $<$ 0};
\node (pro2) [process, left of=dec2, xshift=-3cm] {b=c};
\node (pro3) [process, below of=dec2, yshift=-1.5cm] {a=c};
\node (out1) [io, below of=pro3] {Output: H, V, T};
\node (out2) [io, left of=out1,xshift=-4.5cm] {Output: H, V, T};
\node (pro4) [process, below of=out1] {Plot:H on T and V on T};
\node (stop) [startstop, below of=pro4] {Stop};
\draw [arrow] (start) -- (in1);
\draw [arrow] (in1) -- (pro1);
\draw [arrow] (pro1) -- (if1);
\draw [arrow] (if1) -- node {False} (dec1);
\draw [arrow] (dec1) -- node {True} (pro1a);
\draw [arrow] (pro1a) -- (dec2);
\draw [arrow] (dec2) -- node {False}(pro3);
%\draw [arrow] (if1) -- ++(-5.5,-0) -- ++(-1.5,0) |- node[below right] {True} (out2)
\draw [arrow] (if1) -| node [above right] {True} (out2);
\draw [arrow] (pro2) |- (dec1);
\draw [arrow] (pro3) -- ++(-3.5,-0) -- ++(-2.5,0) |- (dec1);
\draw [arrow] (dec2) -- node {True} (pro2);
\draw [arrow] (dec1) -- ++(2.5,-0) -- ++(3,0) |- node[right] {False} (out1);
\draw [arrow] (out1) -- (pro4);
\draw [arrow] (out2) |- (stop);
\draw [arrow] (pro4) -- (stop);
\end{tikzpicture}
\end{document}
附加問題:如何告訴 LaTex 在兩個進程之間繪製,如圖中的範例
答案1
我想你可能會喜歡:-)
- 上面的流程圖幾乎是從頭開始寫的。
- 而不是過時的
\tikzstyle
節點樣式被定義為 的選項tikzpicture
。 - 但是,如果您希望在文件序言中定義它們,那麼您可以移至
\tikset{<styles definitions>}
序言中 - 如果在主分支位置使用Ti,流程圖程式碼會變得更加簡潔和清晰kZ 庫
chains
及其宏join
- 鏈中節點以及其他節點的一致放置可以使用 TikZ 函式庫
positioning
的語法...=of <node name>
(而非... of = <node name>
MWE 中使用的過時語法)定義節點邊界之間的距離。這樣就可以防止它們最終的重疊。 - 我採取了一些自由,在某些節點中將文字分成幾行。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{chains,
positioning,
quotes,
shapes.geometric}
\makeatletter
\tikzset{suppress join/.code={\def\tikz@after@path{}}}
\makeatother
\begin{document}
\begin{tikzpicture}[
node distance = 6mm and 12mm,
start chain = A going below,
base/.style = {draw, fill=#1,
minimum width=34mm, minimum height=7mm, align=left,
font=\ttfamily},
startstop/.style = {base=red!30, rounded corners},
process/.style = {base=orange!30},
io/.style = {base=blue!30,
trapezium, trapezium stretches body,
trapezium left angle=70, trapezium right angle=110},
decision/.style = {base=green!30, diamond, aspect=1.5},
arr/.style = {semithick,-latex}
]
% nodes in chain
\begin{scope}[nodes={on chain=A, join=by arr}]
\node [startstop] {Start}; % name: A-1
\node [io] {Input:\\ f(), a, b, $\varepsilon$};
\node [process] {c=(a+b)/2};
\node [decision] {if:\\ f(a)*f(b)$>$0}; % A-4
\node [decision] {While:\\ % A-5
f(c) $\not=$ 0 \& \\
$|$f(b) - f(a)$|$ $> \delta$};
\node [process] {c=(a+b)/2};
\node [decision] {if:\\ f(a)*f(c)\textless 0}; % A-7
\node [process] {a=c};
\node [io, suppress join]
{Output: H, V, T};
\node [process] {Plot:\\ H on T and V on T};
\node [startstop] {Stop};
\end{scope}
\node (a) [process, left=of A-7] {b=c};
\node (b) [io, left=of A-9] {Output: H, V, T};
%
\path (A-4) edge["False"] (A-5)
(A-5) edge["True"] (A-6)
(A-7) edge["False"] (A-8)
(A-7) edge["True"] (a)
;
\draw[arr] (A-5.east) to["false"] ++ (2,0) |- (A-9);
\draw[arr] (a) |- (A-5);
\draw[arr] (A-8) -| ([shift={(-1em,-0)}] a.west) % <---
|- (A-5);
\draw[arr] (A-4) -| node[pos=0.1, above] {True}
([shift={(-2em,-2em)}] a.south west) % <---
|- (b);
\draw[arr] (b) |- (A-10);
\end{tikzpicture}
\end{document}
\end{tikzpicture}
\end{document}
附錄:
@Qrrbrbirlbel 的另一個答案提供了一個有趣的想法,因此在這裡測試其對上述命題的適應性。與原來的提議相比,這裡改變了以下內容:
- 刪除
scope
鏈中的放置節點 - 宏
join
(這裡不起作用)被替換為\foreach
循環 - 考慮@Qrrbrbirlbel關於繪製
decision
節點的想法 - 在適當的地方協調使用的
-|-
路徑(明智的) - 決策結果的標籤寫為節點選項
- 節點名稱被重新命名(可以輕鬆地將其與原始答案中的名稱區分開)
- 添加了右側的附加循環箭頭(儘管在我看來,這是邏輯上錯誤的)
生成的圖像更加緊湊,程式碼差異不大,很容易理解:
\documentclass[border=3.141592]{standalone}
\usepackage{tikz}
\usetikzlibrary{
arrows.meta, % arrow tips
chains, % start chain, on chain
ext.paths.ortho, % -|- and |-| path operations
positioning, % ...=of <node>
shapes.geometric % for diamond at "if" node
}
\begin{document}
\begin{tikzpicture}[auto,
node distance = 6mm and 12mm,
start chain = A going below,
arr/.style = {semithick,-Stealth},
base/.style = {draw=#1, semithick, fill=#1!25,
text width=32mm, minimum height=7mm, align=center,
font=\ttfamily,
on chain=A
},
be/.style = {% BeginEnd
base=red, rounded corners},
D/.style = {diamond, draw=#1, fill=#1!50, inner sep=2mm, anchor=center},
if/.style = {base=teal, align=left,
label={[D=teal]north east:}},
lbl/.style = {inner ysep=2pt, font=\small, text=black!75},
lb/.style = {label={[lbl, anchor=north west]south:#1}},
ll/.style = {label={[lbl, anchor=south east]west:#1}},
lr/.style = {label={[lbl, anchor=south west]east:#1}},
pc/.style = {% ProCess
base=orange},
io/.style = {base=blue,
trapezium, trapezium stretches body,
trapezium left angle=70, trapezium right angle=110},
%
every chain label/.style={inner sep=1mm, font=\footnotesize},
off chain/.code={\def\tikz@lib@on@chain{}} % <== defined interruption of chain
]
% nodes
\node [be] {Start}; % name: A-1
\node [io] {Input:\\ f(), a, b, $\varepsilon$};
\node [pc] {c=(a+b)/2};
\node [if,
ll=True,
lb=False] {if:\\ f(a)*f(b)$>$0}; % A-4
\node [if,
lb=False,
lr=True] {While:\\ % A-5
f(c) $\not=$ 0 \& \\
$|$f(b) - f(a)$|$ $> \delta$};
\node [pc] {c=(a+b)/2};
\node [if,
lb=False,
ll=True] {if:\\ f(a)*f(c)\textless 0}; % A-7
\node [pc] {a=c};
\node [io]
{Output: H, V, T};
\node [pc] {Plot:\\ H on T and V on T};
\node [be] {Stop}; % A-11
%% nodes out of chain
\node [pc, off chain,
left=of A-7] {b = c}; % A-12
\node [io, off chain,
left=of A-9] {Output: H, V, T}; % A-13
%%% arrows in main branch
\foreach \i [evaluate=\i as \j using int(\i+1)] in {1,2,...,7, 9,10}
\draw[arr] (A-\i) -- (A-\j);
%%%% arrows on the left
\draw[arr] (A-4) -|-[distance=54mm] (A-13.west); % node distance+text width+2*(inner sep)+distance
\draw[arr] (A-7) -- (A-12);
\draw[arr] (A-8.west) -|-[distance=-50mm] ([yshift=2mm] A-5);
\draw[arr] (A-12) |- ([yshift=-2mm] A-5.west);
\draw[arr] (A-13) |- (A-10);
%%%% arrows on the right
\draw[arr] (A-5) -|-[distance=8mm] (A-9.east);
\draw[arr] (A-10) -|-[distance=12mm] (A-3.east);
\end{tikzpicture}
\end{document}
答案2
像往常一樣,有很多方法
- 聲明節點,
- 放置節點和
- 連接它們。
這裡有兩個解決方案。
第一個使用graphs
庫來聲明節點並連接它們,而chains
庫positioning
用於放置它們。
第二種解決方案使用 a\matrix
將節點放置在網格上。 (不幸的是,matrix of nodes
不能\\
在節點內部輕鬆使用。但是為此,我將提供\n
快捷方式。)這裡也使用
the 來graphs
連接節點。edge
在我看來,它只是提供了比路徑操作更簡單的語法。
在這兩種解決方案中,提供的名稱(例如st'0
、等)也用於設定節點的樣式,先前IO'1
的所有內容'
都用於樣式,例如style st
、style IO
等。一起使用但關鍵是矩陣中的節點仍然有可用的名稱。這將允許將其轉換為圖表。 (不過,我相信如果我們也將命令混合到矩陣中,那麼概述就會丟失。)\matrix
name
alias
<matrix name>-<row>-<column>
matrix
tikzcd
\ar
此show node names
鍵可用於在左上角顯示主要節點的名稱:
我不太喜歡鑽石形狀。我會建議一個chamfered rectangle
選項STYLE if=chamfered
:
我們STYLE if=labeled
可以在普通矩形的右上角放置一個小菱形:
像往常一樣,我使用這些圖表ext.paths.ortho
我的庫tikz-ext
包裹。它提供了路徑操作r-rl
,首先向右繪製一條水平線,然後向目標節點繪製一條垂直線,最後向目標節點繪製一條水平線。
程式碼
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{
arrows.meta, % arrow tips
shapes.geometric, % diamond, trapezium
quotes, % "nodes" on edges
positioning, % left=of
ext.paths.ortho, % r-rl and r-lr path operations
shapes.misc, % chamfered rectangle
%
matrix, % matrix of nodes
chains, % start chain, on chain
graphs, % \graph
}
\tikzset{
COMMON/.style={
/utils/exec=\def\|{\textbar},
node distance = 7mm and 1cm, row sep=7mm, column sep=1cm,
style me/.style args={##1'##2}{style ##1/.try},
style normal/.style={
draw, minimum width=+3.5cm, minimum height=+1cm, align=center},
style st/.append style={
shape=rectangle, style normal, rounded corners, fill=red!30},
style op/.append style={style st},
style IO/.style={
shape=trapezium, trapezium left angle=70, trapezium right angle=110,
style normal, align=left, fill=blue!30},
style PC/.style={
shape=rectangle, style normal, fill=orange!30},
style if/.style={
shape=diamond, style normal, align=left, fill=green!30, aspect=2},
rl/.style={to path={r-rl(\tikztotarget)\tikztonodes}},
lr around/.style={to path={
-|([xshift=-1cm]##1.west)|-(\tikztotarget)\tikztonodes}},
ortho/rl distance=1cm, ortho/lr distance=3.5cm,
vh/.style={to path={|-(\tikztotarget)\tikztonodes}},
hv/.style={to path={-|(\tikztotarget)\tikztonodes}},
},
STYLE if/.is choice, STYLE if/diamond/.style=,
STYLE if/chamfered/.style={style if/.append style=chamfered rectangle},
STYLE if/labeled/.style={style if/.append style={shape=rectangle, label={
[diamond, draw, fill=white, anchor=center, fill=green!30]north east:}}},
MATRIX/.style={n/.style args={##1'##2}{alias={##1'##2}, style me={##1'##2}}},
GRAPHS/.style={
graphs/every graph/.append style={no placement,
nodes={style me/.expand once=\tikzgraphnodename}},
set text/.code=\def\tikzgraphnodetext{##1},
style st/.append style={set text=Start},
style op/.append style={set text=Stop}},
show node names/.style={style me/.append style={
label={[overlay,node font=\small]north west:##1'##2}}}
}
\begin{document}\ttfamily
\begin{tikzpicture}[>=Latex, COMMON, GRAPHS, STYLE if=labeled]
\graph[/tikz/start chain=down going below] {
{[nodes={on chain=down}]
st'0 -> IO'1 / "Input:\\ f(), a, b, $\varepsilon$"
-> PC'1 / "c=(a+b)/2"
-> if'1 / "if:\\f(a)*f(b) $>$ 0"
->["False"] if'2 / "While:\\f(c) $\not=$ 0 \&\\
\|f(b) - f(a)\| $> \delta$"
->["True"] PC'2 / "c=(a+b)/2"
-> if'3 / "if:\\f(a)*f(c) $<$ 0"
->["False"] PC'3 / "a=c",
IO'2 / "Output:\\H, V, T"
-> PC'4 / "Plot:\\H on T and V on T"[align=left]
-> op'0,
},
if'3 ->["True"] PC'5 / "b=c" [left=of if'3]
->[vh] if'2,
if'2 ->[rl, "False" near start] IO'2,
if'1 ->[hv, "True" above right]
IO'3 / "Output:\\H, V, T" [left=of PC'5.west|-IO'2]
->[vh] op'0,
PC'3 ->[lr around=PC'5] if'2
};
\end{tikzpicture}
\begin{tikzpicture}[>=Triangle, COMMON, MATRIX, STYLE if=chamfered]
\newcommand*\n{\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]}
\matrix[matrix of nodes, nodes={anchor=center}] {
& & |[n=st'0]| Start \\
& & \n[n=IO'1] {Input:\\ f(), a, b, $\varepsilon$}; \\
& & |[n=PC'1]| c=(a+b)/2 \\
& & \n[n=if'1] {if:\\f(a)*f(b) $>$ 0}; \\
& & \n[n=if'2] {While:\\f(c) $\not=$ 0 \&\\
\|f(b) - f(a)\| $> \delta$}; \\
& & |[n=PC'2]| c=(a+b)/2 \\
& |[n=PC'5]| b=c
& \n[n=if'3] {if:\\f(a)*f(c) $<$ 0}; \\
& & |[n=PC'3]| a=c \\
\n[n=IO'3] {Output:\\H, V, T};
& & \n[n=IO'2] {Output:\\H, V, T}; \\
& & \n[n=PC'4, align=left] {Plot:\\H on T and V on T}; \\
& & |[n=op'0]| Stop \\
};
\graph[use existing nodes]{
st'0 -> IO'1
-> PC'1
-> if'1
->["False"] if'2
->["True"] PC'2
-> if'3
->["False"] PC'3
-!- IO'2
-> PC'4
-> op'0,
if'2 ->[rl, "False" near start] IO'2,
if'3 ->["True"] PC'5
->[vh] if'2,
if'1 ->[hv, "True" above right] IO'3
->[vh] op'0,
PC'3 ->[lr around=PC'5] if'2
};
\end{tikzpicture}
\end{document}
輸出
答案3
您的問題對我來說並不完全清楚,但我假設您正在嘗試實現類似的目標(箭頭不重疊任何節點,並且在中間的綠色菱形節點中插入換行符):
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}
\tikzset{
startstop/.style={
rectangle,
rounded corners,
minimum width=3cm,
minimum height=1cm,
text centered,
draw=black,
fill=red!30
},
io/.style={
trapezium,
trapezium left angle=70,
trapezium right angle=110,
minimum width=3cm,
minimum height=1cm,
text centered,
draw=black,
fill=blue!30
},
process/.style={
rectangle,
minimum width=3cm,
minimum height=1cm,
text centered,
draw=black,
fill=orange!30
},
decision/.style={
diamond,
minimum width=3cm,
minimum height=1cm,
text centered,
align=center, % add
draw=black,
fill=green!30,
},
arrow/.style={
thick,
->,
>=stealth
}
}
\begin{document}
\begin{tikzpicture}[node distance = 1.3cm, auto]
% Place nodes
\node (start) [startstop] {Start};
\node (in1) [io, below of=start] {Input: f(), a, b, $\varepsilon$};
\node (pro1) [process, below of=in1] {c=(a+b)/2};
\node (if1) [decision, below of=pro1, yshift=-1.5cm] {if: f(a)*f(b)$>$0};
% \node (pro1) [process, below of=in1] {Process 1};
\node (dec1) [decision, below of=if1, yshift=-4cm] {While: f(c) $\not=$ 0 \& \\ $|$f(b) - f(a)$|$ $> \delta$};
\node (pro1a) [process, below of=dec1, yshift=-3cm] {c=(a+b)/2};
\node (dec2) [decision, below of=pro1a, yshift=-1.75cm] {if: f(a)*f(c) $<$ 0};
\node (pro2) [process, left of=dec2, xshift=-3cm] {b=c};
\node (pro3) [process, below of=dec2, yshift=-1.5cm] {a=c};
\node (out1) [io, below of=pro3] {Output: H, V, T};
\node (out2) [io, left of=out1, xshift=-4.5cm] {Output: H, V, T};
\node (pro4) [process, below of=out1] {Plot: H on T and V on T};
\node (stop) [startstop, below of=pro4] {Stop};
\draw [arrow] (start) -- (in1);
\draw [arrow] (in1) -- (pro1);
\draw [arrow] (pro1) -- (if1);
\draw [arrow] (if1) -- node {False} (dec1);
\draw [arrow] (dec1) -- node {True} (pro1a);
\draw [arrow] (pro1a) -- (dec2);
\draw [arrow] (dec2) -- node {False} (pro3);
%\draw [arrow] (if1) -- ++(-5.5,-0) -- ++(-1.5,0) |- node [below right] {True} (out2)
\draw [arrow] (if1) -| node [above right] {True} ([xshift=-1cm]out2.north); % replace to coordinate
\draw [arrow] (pro2) |- (dec1.190); % repplace to coordinate
\draw [arrow] (pro3) -- ++(-3.5,-0) -- ++(-2.5,0) |- (dec1.170); % repplace to coordinate
\draw [arrow] (dec2) -- node {True} (pro2);
\draw [arrow] (dec1) -- ++(2.5,-0) -- ++(3,0) |- node [right] {False} (out1);
\draw [arrow] (out1) -- (pro4);
\draw [arrow] ([xshift=-1cm]out2.south) |- (stop); % replace from coordinate
\draw [arrow] (pro4) -- (stop);
\end{tikzpicture}
\end{document}
我希望這與您想要實現的目標有些接近,並且至少可以幫助您入門。我稍微調整了node distance
一下,讓它看起來不那麼擁擠。
我對相關調整做簡單說明:
- 在節點內新增此選項
align=center
可讓您在節點文字內使用雙反斜線 (\) 新增換行符。 - 您可以使用錨點
<node>.north
和<node>.south
來引用節點的頂部和底部。此外,您還可以新增[xshift=<dim>]
座標以將其向左或向右移動,或[yshift=<dim>]
向上或向下移動。因此,例如,您可以透過分別使用和將節點名稱替換out2
為相關錨點的移動座標來移動左側的箭頭。[xshift=-1cm]out2.north
[xshift=-1cm]out2.north
- 另一種方法是使用所謂的邊界錨點,它們從節點的右側開始以逆時針方式排列,並以度數給出。因此,錨點
<node>.90
通常位於與 相同的位置<node>.north
,但您也可以使用 以外的其他值90
。我使用這種方法在指向中間綠色菱形節點的兩個箭頭之間添加距離。