4

Probably a lame question about how positioning in TikZ works. I'm trying to draw some electrical stuff (starting on the level of single gates) and because many of them repeat over and over, I want to define macros for drawing them. I have this simple thing:

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\def\halfadderplain{%
    \draw +(0,2) -- +(3,2);
    \draw +(0,1) -- +(3,1);
    \draw +(0,0) -- +(3,0);
    \draw +(0.5,-0.5) [fill=white] rectangle +(2.5,2.5);
    \node at +(1.5,1) {QHA};
}

\begin{tikzpicture}
    \coordinate (0,0);
    \halfadderplain;
    \coordinate (3,3);
    \halfadderplain;
\end{tikzpicture}
\end{document}

I want it to do the following: I set up a beginning coordinate and call the macro to draw the component, then I set the coordinate somewhere else and call the draw again. I want to end up with two components drawn like this:

enter image description here

but instead the result is only:

enter image description here

I tried the \newcommand and parameterized the \halfadderplain to set the coordinates and it did properly. I also tried to replace \halfadderplain in above code with its definition and nothing happened, so I think this is not the problem with macro but just my misunderstanding how TikZ computes position. Can somebody help please?

(Please note that using some specific library for drawing this kind of stuff is IS NOT a solution for me.)

2
  • Welcome to TeX.sx! That won't work as paths in TikZ are independent of each other. You will need to do this in one path, or include the first point as a parameter to the macro. Commented Apr 7, 2013 at 19:50
  • Would declaring a new shape be a viable option? Working with nodes is much better since you can use anchors to place stuff. Commented Apr 7, 2013 at 20:40

3 Answers 3

3

Here is a dirty solution, which requires manual placement of the half-adder units; a more clever solution must be possible with TikZ shapes...

EDIT: Following Peter Grill's comment, I removed the second (useless) second argument.

enter image description here

\documentclass{minimal}
\usepackage{tikz}
\begin{document}
\def\halfadderplain#1{%
    \begin{scope}[xshift=#1]
    \draw +(0,2) -- +(3,2);
    \draw +(0,1) -- +(3,1);
    \draw +(0,0) -- +(3,0);
    \draw +(0.5,-0.5) [fill=white] rectangle +(2.5,2.5);
    \node at +(1.5,1) {QHA};
    \end{scope}
}

\begin{tikzpicture}
    \halfadderplain{0};
    \halfadderplain{3cm};
\end{tikzpicture}
\end{document}
3
  • 2
    Why "dirty solution"? You could just accept one parameter which is the coordinate to shift by: \begin{scope}[shift=#1], and call it via \halfadderplain{(A)}; where \coordinate (A) at (0,0);. Commented Apr 7, 2013 at 19:57
  • Thanks guys, this is exactly what I was looking for :) I know there is necessarry to position every unit by hand but that's what i need.
    – Fiisch
    Commented Apr 7, 2013 at 20:08
  • @Fiisch Accepting and upvoting answers is the preferred way here to say “thank you” to users who helped you :)
    – jub0bs
    Commented Apr 7, 2013 at 20:09
2

All paths do not know of each other. The first coordinate you specify with \coordinate …; is not connected to following paths (besides positioning).

You can do it on one path:

\documentclass[tikz]{standalone}
\begin{document}

\def\halfadderplain{
    \foreach \y in {0,1,2} {+(0,\y) -- +(0.5,\y) +(2.5,\y) -- +(3,\y)}
    +(0.5,-0.5) rectangle +(2.5,2.5)
    node [midway] {QHA}
}

\begin{tikzpicture}
    \draw (0,0) \halfadderplain;
    \draw (3,0) \halfadderplain;
\end{tikzpicture}
\end{document}

or as an insert path style:

\documentclass[tikz]{standalone}
\begin{document}
\tikzset{
    halfadderplain/.style={
        insert path={
            \foreach \y in {0,1,2} {+(0,\y) -- +(0.5,\y) +(2.5,\y) -- +(3,\y)}
            +(0.5,-0.5) rectangle +(2.5,2.5)
            node [midway] {QHA}
        }
    }
}
\begin{tikzpicture}
    \draw (0,0) [halfadderplain];
    \draw (3,0) [halfadderplain];
\end{tikzpicture}
\end{document}

Output

enter image description here

1

It's possible to reduce the code : the way to place the nodes like in the other answers is to use xshift, all the coordinates are modified.

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}[qha/.style={minimum width= 2cm, minimum height= 3cm,draw,fill=white}]
\draw  \foreach \y in {0,...,2} {(0,\y) -- (6,\y)};
\foreach \y in {0,3} \node[qha,xshift=\y cm] at (1.5,1) {QHA};
\end{tikzpicture}
\end{document}

and a variant with another style is :

\begin{tikzpicture}[qha/.style={minimum width= 2cm, minimum height= 3cm,draw,fill=white,xshift=#1}]
\draw  \foreach \y in {0,...,2} {(0,\y) -- (6,\y)};
\foreach \y in {0,3} \node[qha=\y cm] at (1.5,1) {QHA};
\end{tikzpicture}

Remark : better is to avoid the second \foreach with only two nodes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .