
첫 번째 출력이 다른 행과 겹치지 않고 두 번째 출력으로 이동하는 것이 가능한 경우 그림과 같이 코드가 겹치지 않도록 코드를 변경하는 방법. 두 번째로 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를 채용하면 순서도 코드가 더욱 간결해지고 명확해집니다.케이
chains
매크로가 포함된 Z 라이브러리join
- 체인과 다른 노드의 일관된 노드 배치로 Ti를 사용할 수 있습니다.케이MWE에서 사용 되지 않는
positioning
구문...=of <node name>
대신 노드 경계 사이의 거리를 정의하는 Z 라이브러리 입니다.... of = <node name>
이를 통해 최종적인 중복이 방지됩니다. - 나는 약간의 자유를 얻었고 일부 노드에서는 여러 줄로 텍스트를 썼습니다.
\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
루프 로 대체됩니다. decision
노드 그리기에 대한 @Qrrbrbirlbel 아이디어를 고려하십시오.-|-
적절한 곳에서 조정된 경로 사용 (합리적)- 결정 결과의 라벨은 노드 옵션으로 기록됩니다.
- 노드 이름이 변경되었습니다(원래 답변의 이름과 쉽게 구별할 수 있음).
- 오른쪽에 추가 루프 화살표가 추가되었습니다(제 생각에는 논리적으로 잘못되었음에도 불구하고).
결과 이미지는 더 컴팩트하며 이해하기 쉬운 코드와 크게 다르지 않습니다.
\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
바로가기를 제공하겠습니다.) 여기서도
는 노드를 연결하는 데 사용됩니다. 제 생각에는 경로 작업 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
. 저는 이 접근 방식을 사용하여 중앙의 녹색 다이아몬드 노드를 가리키는 두 개의 화살표 사이에 거리를 추가했습니다.