4

like the title states, I would like to clip pictures included with graphixs inside a tikzpicture.

The latex sock.tex file producing the picture is the following (it's a sock, not really well drawn, I know, but I'm not very good)

\documentclass{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\begin{scope}[rounded corners, thick]
\draw (0,1) -- (0,0) -- (-0.8,-0.6);
\draw (0.6,1) -- (0.6,-0.3) -- (-0.4,-1.1);
\draw (-0.4, -1.1) -- (-0.8,-0.6);
\draw (-0.8,-0.6) arc (135:310: 0.3225cm and 0.3225cm);
\draw (0,1) -- (0.6, 1);
\draw (0,0.6) -- (0.6, 0.6);
\end{scope}
\draw (0.1,1) -- (0.1,0.6);
\draw (0.2,1) -- (0.2,0.6);
\draw (0.3,1) -- (0.3,0.6);
\draw (0.4,1) -- (0.4,0.6);
\draw (0.5,1) -- (0.5,0.6);
\end{tikzpicture}
\end{document}

and the code in which I include it is the following

\begin{figure}[!htp]
\begin{center}
\begin{tikzpicture}
\node at (0,0) {\includegraphics[clip, scale=1]{pics/sock.pdf}};
\node at (0.3,-0.1) {\includegraphics[clip, scale=1]{pics/sock.pdf}};
\end{tikzpicture}
\caption{Two socks}
\end{center}
\end{figure}

It gives the following result, and of course, I want the bottom sock to be hidden. Which is not the case.

It gives the following result, and of course, I want the bottom sock to be hidden. Which is not the case.

Putting \clip in the sock.tex file doesn't work, as well as copy/pasting it and clippin in only a single of th scopes.

I don't quite know what to do.

Thanks

  • 1
    clip on includegraphics is intended for the case that you specify a smaller bounding box than the actual image size and want the part outside that area to be clipped rather than over-print the surroundings. If you just use clip without specifying any such clipping area it essentially has nothing to do. – David Carlisle Mar 18 '16 at 15:50
  • Alright, I understand why what I did doesn't work... but I still have no clue on how to make my picture work :s – R. Absil Mar 18 '16 at 15:58
  • What/how exactly do you want to clip? – Torbjørn T. Mar 18 '16 at 15:59
  • I'm also confused: Do you want to include the standalone in another document? Please clarify the context of the situation. – Alenanno Mar 18 '16 at 15:59
  • @R.Absil I couldn't guess the intended output from the code shown, – David Carlisle Mar 18 '16 at 15:59
5

If you arrange your commands inside one closed path, you can apply fill and cover what it's behind the sock. And a simple scope can be used for a second sock. No need for includegraphics and two files.

\documentclass[border=2mm]{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\begin{scope}[thick]
\draw[fill=green!30!red] (0,1)[rounded corners] -- (0,0) -- (-0.8,-0.6) arc (135:310: 0.3225cm and 0.3225cm)--(0.6,-0.3)[sharp corners]--(0.6,1)-- cycle;
\draw (-0.4, -1.1) -- (-0.8,-0.6);
\draw (0,1) -- (0.6, 1);
\draw (0,0.6) -- (0.6, 0.6);
\end{scope}
\draw (0.1,1) -- (0.1,0.6);
\draw (0.2,1) -- (0.2,0.6);
\draw (0.3,1) -- (0.3,0.6);
\draw (0.4,1) -- (0.4,0.6);
\draw (0.5,1) -- (0.5,0.6);
\begin{scope}[shift={(3mm,-3mm)}]
\begin{scope}[thick]
\draw[fill=green!30!red] (0,1)[rounded corners] -- (0,0) -- (-0.8,-0.6) arc (135:310: 0.3225cm and 0.3225cm)--(0.6,-0.3)[sharp corners]--(0.6,1)-- cycle;
\draw (-0.4, -1.1) -- (-0.8,-0.6);
\draw (0,1) -- (0.6, 1);
\draw (0,0.6) -- (0.6, 0.6);
\end{scope}
\draw (0.1,1) -- (0.1,0.6);
\draw (0.2,1) -- (0.2,0.6);
\draw (0.3,1) -- (0.3,0.6);
\draw (0.4,1) -- (0.4,0.6);
\draw (0.5,1) -- (0.5,0.6);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

5

The pic facility of TikZ has the disadvantage of repeating the code in the PDF output which adds to the overall file size.

For repeated objects from two instances upwards it is better to save the object as a PDF Form XObject and insert references to it as often as desired. The xsavebox package can be used for this purpose:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xsavebox}

\begin{document}
\xsbox{Sock}{%
  \tikz{
    \begin{scope}[thick]
    \draw[fill=green!30!red] (0,1)[rounded corners] -- (0,0) -- (-0.8,-0.6) arc (135:310: 0.3225cm and 0.3225cm)--(0.6,-0.3)[sharp corners]--(0.6,1)-- cycle;
    \draw (-0.4, -1.1) -- (-0.8,-0.6);
    \draw (0,1) -- (0.6, 1);
    \draw (0,0.6) -- (0.6, 0.6);
    \end{scope}
    \draw (0.1,1) -- (0.1,0.6);
    \draw (0.2,1) -- (0.2,0.6);
    \draw (0.3,1) -- (0.3,0.6);
    \draw (0.4,1) -- (0.4,0.6);
    \draw (0.5,1) -- (0.5,0.6);
  }%
}%
\begin{tikzpicture}
  \begin{scope}[inner sep=0pt, outer sep=0pt]
    \node at (0,0) {\theSock};
    \node [scale=1.1] at (0.3,-0.2) {\theSock};
  \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

4

Solution with clipping

This answer provides a solution using clip to address the subject of the question. The socks are constructed using macros and pics:

  • The outline of the sock is defined as macro \SockOutline, because it will later be used as part of a clip path.

    The line is defined as a connected closed path in one \path command. Splitting the outline in several \path or \draw commands will destroy the line joins.

    Then the drawn outline is defined as pic with name sock outline.

  • The inner part of the sock is put in pic with name inside of sock.

  • The outline and inside part are combined in pic with name sock.

Now, the actual clipping and drawing follows. The left sock is drawn with clipping in force, then the right foreground sock is drawn without clipping.

The clipping area is constructed using the even odd rule. There are two areas, the full drawing area and the foreground sock. The latter area is covered twice (even), which means, it is outside of the final clipping path.

The full example:

\documentclass{standalone}

\usepackage{tikz}

\begin{document} 
\newcommand*{\SockOutline}{%
  (0, 1)
  { [rounded corners] -- (0, 0) }
  -- (-0.8, -0.6)
  arc (135:310:0.3225cm)
  { [rounded corners] -- (0.6, -0.3) }
  -- (0.6, 1)
  -- cycle
}   
\begin{tikzpicture}[   
  sock outline/.pic={
    \draw[thick] \SockOutline;   
  },
  inside of sock/.pic={
    \draw[thick]
      (-0.4, -1.1) -- (-0.8,-0.6)
      (0, 0.6) -- (0.6, 0.6)
    ;  
    \draw[thin]
      \foreach \x in {0.1, 0.2, ..., 0.5} {
        (\x, 1) -- (\x, 0.6)
      }  
    ;
  },
  sock/.pic={
    \path
      pic {sock outline}
      pic {inside of sock}
    ;
  },
]
  \begin{scope}[even odd rule, overlay]
    \clip
      (-2, -2) rectangle (2, 2)
      [shift={(0.2, -0.1)}] \SockOutline
    ;
    \draw[overlay=false] pic {sock};
  \end{scope}
  \draw (0.2, -0.1) pic {sock};
\end{tikzpicture}
\end{document}

Result

3

Should you need to draw a lot of socks I would recommending using a pic, which are small snippets of TikZ that can be reused easily. You define a pic with sock/.pic={<code for sock>}, and use it as \pic at (0,0) {sock};. So, borrowing Ignasi's sock:

\documentclass{article}
\usepackage{tikz}
\tikzset{sock/.pic={
\begin{scope}[thick]
\draw[fill=green!30!red] (0,1)[rounded corners] -- (0,0) -- (-0.8,-0.6) arc (135:310: 0.3225cm and 0.3225cm)--(0.6,-0.3)[sharp corners]--(0.6,1)-- cycle;
\draw (-0.4, -1.1) -- (-0.8,-0.6);
\draw (0,1) -- (0.6, 1);
\draw (0,0.6) -- (0.6, 0.6);
\end{scope}
\draw (0.1,1) -- (0.1,0.6);
\draw (0.2,1) -- (0.2,0.6);
\draw (0.3,1) -- (0.3,0.6);
\draw (0.4,1) -- (0.4,0.6);
\draw (0.5,1) -- (0.5,0.6);
}}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}
\pic at (0,0) {sock};
\pic at (0.2,-0.1) {sock};
\end{tikzpicture}
\caption{Two socks}
\end{figure}
\end{document}

enter image description here

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.