Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have two paths I use for clipping. Is there a way to combine the two paths? I want the second clip path to clip the first path so I can create more complex shapes.

e.g., (Note this is just a simple example to express a specific instance of the general case)

\fbox{\begin{tikzpicture}
\begin{scope}
\clip (-0.8, -0.8) rectangle (0.8,0.8) (0,0) circle (1);
\fill[color=black] (-10, -10) rectangle (10,10);
\end{scope}
\end{tikzpicture}}

It would be the inner rectangle with corners clipped by the circle:

enter image description here

But I would like to fill the inside of all the individual paths(e.g., I want to take the intersection of the paths or do some type of algebra on the paths).

share|improve this question
2  
Minor nitpick: If you combine the example paths then you have a circle with 4 bumps on it. What you might want is the intersection and you can clip twice or more e.g. \clip (-0.8, -0.8) rectangle (0.8,0.8);\clip (0,0) circle (1); –  percusse Jun 5 '12 at 0:25
1  
I've just tested percusse's suggestion and it gives what I think you're after (hard to tell exactly without a picture). Basically, in a scope then clips accumulate so effectively this involves taking the intersection. If you want more complicated "algebra" then it would be worth your while providing some pictures of what you're aiming for. –  Loop Space Jun 5 '12 at 6:47
    
I initially tried percusse's solution and i only got one clip path used. I tried again it is working and gives the object I am looking for. @AndrewStacey An algebra is the union, intersection, etc of paths. Same as venn diagrams BUT you take the regions final border instead of the region itself. If &A and &B are two closed paths containing the regions A and B then &A U &B = &(A U B), etc... –  AbstractDissonance Jun 5 '12 at 16:30
    
I am well aware of what an algebra is and I know what I would expect the result to look like, but adding pictures is a good way to ensure that everyone is clear what is wanted. –  Loop Space Jun 5 '12 at 17:39

1 Answer 1

up vote 3 down vote accepted

Here you go. Special thanks again to Brandon Kuczenski for making me aware of arrayjobx in this answer.

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{arrayjobx}

\newcommand{\multiclip}[3]{% number of clippings, clipping commands (connect with &), draw commands
\newarray\temp%
\readarray{temp}{#2}%
\foreach \x in {1,...,#1}%
{ \begin{scope}%
        \pgfmathtruncatemacro{\xt}{\x}%
        \temp(\xt)%
        #3%
    \end{scope}%
}%
\delarray\temp%
}

\begin{document}

\fbox{\begin{tikzpicture}
    \multiclip{2}{\clip (-0.8, -0.8) rectangle (0.8,0.8);&\clip (0,0) circle (1);}{\fill[color=red](-10,-10)rectangle(10,10);}
\end{tikzpicture}}

\fbox{\begin{tikzpicture}
    \multiclip{5}{\clip(-1,-1)circle(0.8); &\clip(-1,1)circle(0.8); &\clip(1,-1)circle(0.8); &\clip(1,1)circle(0.8); &\clip(0,0)circle(0.8);}{\fill[color=red](-10,-10)rectangle(10,10); \draw(-5,-5)-- (5,5); \draw(-1,-1)rectangle(1,1);}
\end{tikzpicture}}

\end{document}

The command \multiclip takes three arguments:

  • the number of areas to clip
  • The cammands for clipping (you have to specify whole commands, e.g \clip (0,0) circle (1);. In princple, one could alter the code to \clip \temp(\xt); so one would only have to write (0,0) circle (1). But in the former variant, you can decide do e.g. draw some of the clip areas). The single commands have to be concatenated via &.
  • the drawing commands that will appear in all clipping areas.

enter image description here


Edit 1: For an intersection clip, you can either use nested scopes with clip commands and put the draw commands into the innermost scope, or you can simply give the clip commands in succession. However, the bounding box is strang in any case. I constructed an example with 5 overlapping circles. When done manually the large bounding box results. When done via a macro however, the bounding box is the maximal one, e.g. in your example a box of 20 x 20 caused by the \fill (-10,-10) -- (10,10);. I have no idea why that happens, but you can fix it via using a \useasboundingbox before. Here are the final commands, \unionclip and \intersectionclip:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{arrayjobx}
\usepackage{xifthen}

\newcommand{\unionclip}[3]{% number of clippings, clipping commands (connect with &), draw commands
\newarray\temp%
\readarray{temp}{#2}%
\foreach \x in {1,...,#1}%
{ \begin{scope}%
        \pgfmathtruncatemacro{\xt}{\x}%
        \temp(\xt)%
        #3%
    \end{scope}%
}%
\delarray\temp%
}

\newcommand{\intersectionclip}[3]{% number of clippings, clipping commands (connect with &), draw commands
\newarray\temp%
\readarray{temp}{#2}%
%\begin{scope}%
\foreach \x in {1,...,#1}%
{   \pgfmathtruncatemacro{\xt}{\x}%
    \temp(\xt)%
}
#3%
%\end{scope}%
\delarray\temp%
}

\begin{document}

\fbox{\begin{tikzpicture}
    \unionclip{2}
                        {\clip (-0.8, -0.8) rectangle (0.8,0.8);&
                         \clip (0,0) circle (1);}
                        {\fill[color=green](-10,-10)rectangle(10,10);}
\end{tikzpicture}}
\fbox{\begin{tikzpicture}
    \unionclip{5}
                        {\clip(-1,-1)circle(0.8);&
                         \clip(-1,1)circle(0.8);&
                         \clip(1,-1)circle(0.8);&
                         \clip(1,1)circle(0.8);&
                         \clip(0,0)circle(0.8);}
                        {\fill[color=green](-10,-10)rectangle(10,10);
                         \draw[thick](-5,-5)-- (5,5);
                         \draw[densely dashed,ultra thick](-1,-1)rectangle(1,1);}
\end{tikzpicture}}

\begin{tikzpicture}
\draw[fill=green,fill opacity=0.25](-1,-1)circle(2.5);
\draw[fill=green,fill opacity=0.25](-1,1)circle(2.5);
\draw[fill=green,fill opacity=0.25](1,-1)circle(2.5);
\draw[fill=green,fill opacity=0.25](1,1)circle(2.5);
\draw[fill=green,fill opacity=0.25](0,0)circle(2.5);
\draw[densely dashed,ultra thick](-1,-1)rectangle(1,1);
\end{tikzpicture}

\fbox{
\begin{tikzpicture}
\clip(-1,-1)circle(2.5);
\clip(-1,1)circle(2.5);
\clip(1,-1)circle(2.5);
\clip(1,1)circle(2.5);
\clip(0,0)circle(2.5);
    \fill[color=green](-10,-10)rectangle(10,10);
    \draw[densely dashed,ultra thick](-1,-1)rectangle(1,1);
\end{tikzpicture}}

\fbox{\begin{tikzpicture}
    \useasboundingbox (-1.5,-1.5) rectangle (1.5,1.5);  
    \intersectionclip{2}
                        {\clip (-0.8, -0.8) rectangle (0.8,0.8);&
                         \clip (0,0) circle (1);}
                        {\fill[color=green](-10,-10)rectangle(10,10);}
\end{tikzpicture}}
\fbox{\begin{tikzpicture}
    \useasboundingbox (-1.5,-1.5) rectangle (1.5,1.5);  
    \intersectionclip{5}
                        {\clip(-1,-1)circle(2.5);&
                         \clip(-1,1)circle(2.5);&
                         \clip(1,-1)circle(2.5);&
                         \clip(1,1)circle(2.5);&
                         \clip(0,0)circle(2.5);}
                        {\fill[color=green](-10,-10)rectangle(10,10);
                         \draw[densely dashed,ultra thick](-1,-1)rectangle(1,1);}
\end{tikzpicture}}

\end{document}

enter image description here

share|improve this answer
    
You are producing the union, which is nice but could you also produce the interesection? (which is simply concatenating the clip commands) You almost have an algebra if you do that and it would be very useful extension to tikz. \tikzunion{clip1}{clip2} would union clip1 and clip2 in a similar way you have while \tikzintersection{clip1}{clip2} would produce the intersection clip. –  AbstractDissonance Jun 8 '12 at 18:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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