I've been working on a flow diagram or block diagram using Tikz to show a simplified camera transfer function. I've gotten as far as the code below, but I have a few questions remaining.
I started with this example, which uses a matrix for node layout. Please let me know if that was a bad starting point.
My questions are as follows
-
How on earth do you make a simple square that won't deform when you put stuff in it, or at least will stay square. For the first block, I just wanted a square with a horizontal line through it. This turned complicated and I couldn't do it without a new tikz picture within the matrix, and even then there was some extra space after the node before the beginning of the arrow leaving it so I had to use negative space to remove it. Is there an easier way to do this?
-
I found I couldn't just scale the Integral symbol because it's a math symbol which wants to resize itself. I had to use bigints package to do this. Is there some way via Tikz to just scale a symbol or text like that? So I could use a normal
$\int$
and scale it with Tikz? -
In the the second-last block (empty right now), I would like a line similar to the first block, but that goes up in little steps like a stairway (specifically, like an ADC transfer function). Is there a way to do this? I thought maybe a sawtooth wave rotated 90 degrees or something.
-
Why do the connecting lines seem to continue slightly past the end of the arrows so that the arrow tips are not sharp?
Thanks.
\documentclass{article}
\usepackage[a4paper, landscape]{geometry}
\usepackage{tikz}
\usepackage{bigints}
\usetikzlibrary{shapes.geometric,shapes.arrows,decorations.pathmorphing}
\usetikzlibrary{matrix,chains,scopes,positioning,arrows,fit}
\begin{document}
\begin{tikzpicture}[
tip/.style={->,shorten >=0.007pt}
]
% Place all element in a matrix of nodes, called m
\matrix (m) [matrix of nodes,
column sep=5mm,
row sep=1cm,
nodes={draw, % General options for all nodes
line width=1pt,
anchor=center,
text centered,
sharp corners,
minimum width=1.5cm,
minimum height=1.5cm,
inner sep=0em,
},
% Define styles for some special nodes
right iso/.style={isosceles triangle,scale=0.5,sharp corners, anchor=center, xshift=-4mm},
txt/.style={text width=1.5cm,anchor=center},
empty/.style={draw=none},
noborder/.style={ draw=none,text width=1.5cm,anchor=center}
]
{
% First row of symbols
|[noborder]| {Input}
&
|[empty]|{\begin{tikzpicture}[inner sep=0em]
\node[draw, rectangle, minimum size=1.5cm]{};
\draw (-.75,-.75) -- (.75,.75);
%\draw (0,0) -- (1.5,1.5);
\end{tikzpicture}
}
\!\!\!\!
& |[noborder]| {Output 1}
&
{$\bigints$}
& |[noborder]| {Output 2}
& |[empty]|{\begin{tikzpicture}[inner sep=0em]
\node[draw, rectangle, minimum size=1.5cm]{};
\draw (-.75,-.75) -- (.3,.3) -- (.75,.3);
\end{tikzpicture}
}
\!\!\!\!
& % m-1-7
|[noborder]| {Output 3}
& % m-1-8
|[empty]|{\begin{tikzpicture}[inner sep=0em]
\node[draw, rectangle, minimum size=1.5cm]{};
\draw (-7.5mm,-7.5mm) -- (-6.5mm,-7.5mm);
\draw (-6.5mm,-7.5mm) -- (-6.5mm,-6.5mm);
\end{tikzpicture}
}
\!\!\!\!
& |[noborder]| {Ouput 4}
& % m-1-10
|[empty]|{\begin{tikzpicture}[inner sep=0em]
\node[draw, rectangle, minimum size=1.5cm]{};
\draw (-7.5mm,-6.5mm) .. controls (-1.5mm,-7.5mm) and (1.5mm,7.5mm) .. (7.5mm,6.5mm);
\end{tikzpicture}
}
\!\!\!\!
& |[noborder]| {Final \\ Output}
\\
}; % End of matrix
% Now, connect all nodes in a chain.
{ [start chain,every on chain/.style={join}, every join/.style={line width=1pt}]
\chainin (m-1-1);
\chainin (m-1-2) [join=by tip];
\chainin (m-1-3) [join=by tip];
\chainin (m-1-4) [join=by tip];
\chainin (m-1-5) [join=by tip];
\chainin (m-1-6) [join=by tip];
\chainin (m-1-7) [join=by tip];
\chainin (m-1-8) [join=by tip];
\chainin (m-1-9) [join=by tip];
\chainin (m-1-10) [join=by tip];
\chainin (m-1-11) [join=by tip];
};
\end{tikzpicture}
\end{document}
Best Answer
Here's some answers:
Use the
regular polygon
shape (withregular polygon sides=4
) from theshapes.geometric
library (which I see you are already using). Using this, I could draw the squares as you (presumably) wanted. I drew the extras in afterwards using the node anchors for positioning.You can scale nodes wholesale by specifying the scaling on the node itself. In this particular case you want to scape the contents but not the node shape. One way to do this is to double-up the node: draw an empty node initially and then go back later and put the contents in (scaled appropriately).
You found the answer to this yourself. Excellent!
I don't know why, but it's something to do with specifying the
by
option on thejoins
. I found that by putting the style in to theevery join/.style={->}
then the arrows were correct again. It's also nothing to do with thetip
style as\draw[tip] (0,0) -- (1,0);
works as it should. So presumably something in how thejoin
s are rendered is preventing the automatic shortening that ought to happen when an arrow tip is added. If you can isolate this behaviour, it might be worth submitting it as a bug.Here's my version of your code.
With result