13

Does TikZ have a copy command? the copy command means, e.g.,

I draw a rectangle first, then I draw whatever e.g., circle, writing text etc. in the rectangle. let me define a source object that includes all objects in the rectangle and the rectangle itself. Now I want to copy the source object based on the lower left corner of rectangle to a new position.

@Martin @Jan @Caramdir, following is an example, but it has some error. please also refer to my comment.

\documentclass[titlepage,a4paper]{article}

\usepackage[english]{babel}
\usepackage{TikZ}   %Create PostScript and PDF graphics in TeX

\begin{document}
\begin{tikzpicture}[scale=0.962661,thick]
  \foreach \xbase/\ybase in {0mm/0mm,46.700000mm/0mm}
  {
    %grid line
    \draw[xstep=11.200000mm,ystep=12.051000mm] (\xbase,\ybase) grid (\xbase + 44.800000mm,\ybase + 36.153000mm);
  }
\end{tikzpicture}

\end{document}

@Martin @Jan @Caramdir, i updated the above example. it is better except that the most left vertical line of right grid is missing.

\documentclass[titlepage,a4paper]{article}

\usepackage[english]{babel}
\usepackage{TikZ}   %Create PostScript and PDF graphics in TeX

\begin{document}
\begin{tikzpicture}[scale=0.962661,thick]
  \foreach \xbase/\ybase/\xoffset in {0mm/0mm/0mm,44.800000mm/0mm/1.9mm}
  {
    %grid line
    \draw[xstep=11.200000mm,ystep=12.051000mm,xshift=\xoffset] (\xbase,\ybase) grid (\xbase + 44.800000mm,\ybase + 36.153000mm);
  }
 \end{tikzpicture}

 \end{document}

it seemed that grid always uses the origin (0,0) as its reference. my way is to add shift to the base point and cares about the coordinates by myself. but the most left vertical line of right grid is missing. i don't know why. it looked like that the line should be in the range of the grid.

is there a rationale for this? i mean make grid use (x,y) instead of (0,0) as the reference point.

3
  • Related question: "How to rotate as copied in tikz" Feb 26, 2011 at 12:25
  • @Martin thank you for your direction. after reading the link, foreach loop seems a solution. define the base point and new position points in loop variable, then draw everything in loop body.
    – warem
    Feb 26, 2011 at 13:14
  • Just adding a comment many years on (in case someone stumbles across this question) that a feasible solution to this now would be to use the pic syntax to define repeatable "units" of TikZ code. Aug 30, 2021 at 19:41

2 Answers 2

8

Other than using the \foreach command or defining a new command, you may repeat pictures by at least two other ways. (solution to the grid problem is found at the end of my answer)

1- (not tikz specific) : use the \newsavebox, \savebox and \usebox commands. The advantage of savebox is that the picture is not redrawn everytime it is called. For example:

\documentclass{minimal}

\usepackage{tikz}

\begin{document}

\newsavebox{\test}
\savebox{\test}{\tikz \draw[red] (0,0) circle (1cm);}

\begin{tikzpicture}
\draw (0,0) node {\usebox{\test}};
\draw (7,0) node {\usebox{\test}};
\end{tikzpicture}


\end{document}

2- (tikz specific) Use the object-oriented capabilities of tikz and pgf. The details are found in the tikz manual. For example, the code found on page 554 of the manual:

\documentclass{minimal}

\usepackage{tikz}
\usepgfmodule{oo}

\begin{document}

\pgfooclass{stamp}{ % This is the class stamp
    \method stamp() { % The constructor 
    }
    \method apply(#1,#2) { % Causes the stamp to be shown at coordinate (#1,#2)
        %Draw the stamp:
        \node [rotate=20] at (#1,#2) {Passed};
    }
}
\pgfoonew \mystamp=new stamp()
\begin{tikzpicture}
        \mystamp.apply(1,2)
        \mystamp.apply(3,4)
\end{tikzpicture}

\end{document}

About the grid problem. I don't have a good explanation about why the problem is occurring other than the shift in coordinates isn't being treated by tikz the way you expect them to (not much of an explanation I admit). A good way to solve the problem is to use the scope environment, and shift the whole environment, as described by the following code (I somewhat simplified your loop to make the scope environment stand out):

\begin{tikzpicture}[scale=1,thick]
  \foreach \xoffset in {0,5.2}
  {
    \begin{scope}[shift={(\xoffset,0)}]
        \draw[xstep=1,ystep=1] (0,0) grid (5,5);
    \end{scope}
  }
\end{tikzpicture}

The scope environment acts as box that may be moved around (shifted or rotated) as a whole. If you are familiar with pstricks, it is similar to the \rput command.

2
  • your two method both worked. i prefer to the first method because i program with pure c (not at all c++). but, comparing with \foreach command or defining a new command, which one is better or more efficient? on the other hand, could you please have a look at the question about grid in my original example?
    – warem
    Mar 1, 2011 at 5:24
  • @warem: I added a solution to your grid problem : use the scope environment.
    – Frédéric
    Mar 1, 2011 at 6:15
14

If I had to use the same contents several times in different places, I would define a new tex command that draws all the objects, and then use it at different locations, possibly with scope and shifting. Something like this:

\newcommand\mytikzcontents{
  \draw (0,0) rectangle (4,5);
  \draw (1,1) circle (1cm);
  \draw[dashed,->] (4,5) -- (1,1);
}

and then inside the tikzpicture I would use it as

\begin{scope}[xshift=2cm,yshift=3cm]
   \mytikzcontents
\end{scope}

Or you could make the xshift and yshift arguments of the command.

5
  • i just start to learn tikz. now i don't know what scope means. i will refer it to pgfmanual. your method is similar to foreach loop i think. it is a good idea to define a new command to draw the source objects then use it wherever i want. thank you.
    – warem
    Feb 26, 2011 at 14:55
  • @warem: The scope basically passes its options to all the drawing commands inside the scope (plus it localizes clipping).
    – Caramdir
    Feb 26, 2011 at 16:26
  • @Martin @Jan @Caramdir i added an example in the original text. it drew two girds which are exactly same. the left one's lower left corner is (0,0), the right one's is (46.7,0). there is a gap between the two girds. the gap is 1.9. but the right grid omit the gap. it is something about coordinate transformation. but the commad grid always counted on from (0,0).
    – warem
    Feb 28, 2011 at 12:05
  • @Martin @Jan @Caramdir i updated the example in the original text. please check it.
    – warem
    Mar 1, 2011 at 3:54
  • Is there a way to change your mytikzcontents any coordinate? May 15, 2018 at 17:53

You must log in to answer this question.

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