
como alterar o código para que não se sobreponha como na imagem se for possível que o primeiro vá para a segunda saída sem sobrepor outras linhas. Em segundo lugar, existe outra possibilidade de criar uma nova linha dentro da seção if.
Obrigado pelo seu apoio.
\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}
Pergunta adicional: Como dizer ao LaTex para desenhar entre dois processos como o exemplo da imagem
Responder1
Acho que você pode ter gostado :-)
- O fluxograma acima foi escrito quase do zero.
- Em vez de nós obsoletos
\tikzstyle
, os estilos são definidos como opções detikzpicture
. - No entanto, se você preferir defini-los no preâmbulo do documento, poderá colocá-los
\tikset{<styles definitions>}
no preâmbulo - O código do fluxograma torna-se mais conciso e claro, se na posição do ramo principal for empregado TikBiblioteca Z
chains
com sua macrojoin
- A colocação consistente de nós na cadeia, bem como de outros nós, permite o uso de TikBiblioteca Z
positioning
cuja sintaxe...=of <node name>
(em vez da obsoleta... of = <node name>
usada em seu MWE) define distâncias entre as bordas dos nós. Desta forma evitam-se as suas eventuais sobreposições. - Tomei uma certa liberdade e em alguns nós escrevo texto em várias linhas.
\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}
Termo aditivo:
A outra resposta do @Qrrbrbirlbel fornece uma ideia intrigante, então aqui está um teste de sua adaptação à proposição acima. Isto é, em comparação com a proposição original, alterado o seguinte:
- removido
scope
para colocar nós em cadeia - macro
join
(que aqui não funciona) é substituída por\foreach
loop - considere a ideia do @Qrrbrbirlbel sobre desenhar
decision
nós - caminho usado
-|-
coordenado onde for apropriado (sensato) - rótulos de resultado de decisão são escritos como opções de nós
- os nomes dos nós são renomeados (isso pode ser fácil de distinguir dos nomes na resposta original)
- adicionada é uma seta de loop adicional à direita (apesar de - na minha opinião - ser logicamente errado)
A imagem resultante é um código mais compacto e não muito diferente que pode ser fácil de entender:
\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}
Responder2
Como sempre, há muitas maneiras
- para declarar nós,
- para colocar nós e
- para conectá-los.
Aqui estão duas soluções.
O primeiro usa a graphs
biblioteca para declarar nós e conectá-los enquanto o chains
e a positioning
biblioteca são usados para colocá-los.
A segunda solução usa \matrix
para colocar os nós em uma grade. (Infelizmente, with matrix of nodes
the \\
não pode ser usado facilmente dentro de um nó. Mas para isso, fornecerei o \n
atalho.)
The graphs
também é usado aqui para conectar os nós. Ele apenas fornece uma sintaxe mais fácil que a edge
operação do caminho, na minha opinião.
Em ambas as soluções , o nome fornecido, por exemplo st'0
, , , etc. também é usado IO'1
para estilizar o nó, tudo o que vem antes de '
é usado para um estilo, por exemplo style st
, , style IO
, etc. mas a chave para que os nós da matriz ainda tenham seus nomes disponíveis. Isso permitiria que o texto fosse transformado em um diagrama. (No entanto, acredito que a visão geral será perdida se também misturarmos comandos na matriz.)\matrix
name
alias
<matrix name>-<row>-<column>
matrix
tikzcd
\ar
A show node names
chave pode ser usada para exibir o nome dos nós principais no canto superior esquerdo:
Não gosto muito do formato do diamante. Vou sugerir um chamfered rectangle
com a STYLE if=chamfered
opção:
Com STYLE if=labeled
podemos ter um pequeno diamante no canto superior direito de um retângulo normal:
Como sempre acontece com esse tipo de diagrama, estou usando a ext.paths.ortho
biblioteca do meutikz-ext
pacote. Ele fornece a operação de caminho r-rl
que primeiro desenha uma linha horizontal para a direita, depois uma linha vertical para o nó de destino e uma linha horizontal de volta para o destino.
Código
\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}
Saída
Responder3
Sua pergunta não está totalmente clara para mim, mas presumo que você esteja tentando conseguir algo assim (a seta não se sobrepõe a nenhum nó e uma quebra de linha é inserida no nó verde em forma de diamante no meio):
\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}
Espero que isso esteja um pouco próximo do que você deseja alcançar e pelo menos possa ajudá-lo a começar. Ajustei um node distance
pouco para parecer menos apertado.
Deixe-me acrescentar uma breve explicação sobre os ajustes relevantes:
- Adicionar a opção
align=center
a um nó permite adicionar quebras de linha usando uma barra invertida dupla (\) dentro do texto do nó. - Você pode usar as âncoras
<node>.north
e<node>.south
para se referir à parte superior e inferior de um nó. Além disso, você pode adicionar[xshift=<dim>]
a uma coordenada para deslocá-la para a esquerda ou direita ou[yshift=<dim>]
para cima ou para baixo. Portanto, você pode, por exemplo, deslocar a seta à esquerda substituindo o nome do nóout2
pela coordenada deslocada da âncora relevante usando[xshift=-1cm]out2.north
e[xshift=-1cm]out2.north
respectivamente. - Uma abordagem alternativa é usar as chamadas âncoras de borda, que são dispostas no sentido anti-horário, começando no lado direito do nó e são dadas em graus. Portanto, a âncora
<node>.90
normalmente ficaria na mesma posição que<node>.north
, mas você também pode usar outros valores além de90
. Usei essa abordagem para adicionar uma distância entre as duas setas que apontam para o nó do diamante verde no meio.