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.)

  • 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. – Qrrbrbirlbel Apr 7 '13 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. – Qrrbrbirlbel Apr 7 '13 at 20:40
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}
  • 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);. – Peter Grill Apr 7 '13 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 Apr 7 '13 at 20:08
  • @Fiisch Accepting and upvoting answers is the preferred way here to say “thank you” to users who helped you :) – jub0bs Apr 7 '13 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.