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 would like to make a closed smooth path, and then partition it into several subparts each of which would have a different color. For the moment, the best I could come up with was to put another closed path inside with a different background color.

\begin{tikzpicture}
 \draw[ultra thick,color=black,fill=yellow]
  plot[smooth cycle]
  coordinates{
   (0,2) (2.2,2.2) (3.1,3.3) (6,3) (6,0) (0,0)
  };
 \draw[thick, draw=gray,fill=red]
  plot[smooth cycle] coordinates{(2,1.8) (3,2.3) (5,2.3) (5,1) (2,1)};
\end{tikzpicture}

But what I would really want to do would be to be able to draw lines separating the figure into these partitions and then change the background in each of these partitions. For instance with lines like there :

thing

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

Another example using multiple clipping regions with two "arbitrary" paths (with some conditions: both paths should intersect respectively left/right and bottom/top boundaries of current bounding box).

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
  \begin{scope}
    \draw[clip, preaction={draw, ultra thick, double distance=0pt}]
    plot[smooth cycle]
    coordinates{
      (0,2) (2.2,2.2) (3.1,3.3) (6,3) (6,0) (0,0)
    };
    % first path (a)
    \path[name path=a] plot[domain=-1:7,samples=100](\x,{.5*sin(\x*3 r)+1});
    % second path (b)
    \path[name path=b] plot[domain=-1:4,samples=100]({.5*sin(\x*4 r)+2},\x);
    % current bounding box (boundaries)
    \path[name path=boundaries]
    (current bounding box.south west)
    rectangle
    (current bounding box.north east);
    % two intersestion for each path (ai-1,ai-2) and (bi-1,bi-2)
    \path[name intersections={of=a and boundaries,name=ai}];
    \path[name intersections={of=b and boundaries,name=bi}];


    \foreach \regcol/\pta/\ptb in {%
      red/north/east,% north of path a and east of path b
      green/north/west,% north of path a and west of path b
      yellow/south/east,% ...
      blue/south/west% ...
    }{
      \begin{scope}
        % clipping region path a
        \clip
        plot[domain=-1:7,samples=100](\x,{.5*sin(\x*3 r)+1})
        |- (current bounding box.\pta) -| (ai-1);
        % clipping region path b
        \clip
        plot[domain=-1:4,samples=100]({.5*sin(\x*4 r)+2},\x)
        -| (current bounding box.\ptb) |- (bi-1);
        \fill[\regcol]
        (current bounding box.south west)
        rectangle
        (current bounding box.north east);
      \end{scope}
    }
    % drawing pathes
    \draw plot[domain=-1:7,samples=100](\x,{.5*sin(\x*3 r)+1});
    \draw plot[domain=-2:4,samples=100]({.5*sin(\x*4 r)+2},\x);
  \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Edit: A second example with factorized definitions of paths (and interesting effects of partition).

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\newcommand\plota{plot[smooth,domain=-1:7,samples=100](\x,{2*sin(\x*3 r)+1})}
\newcommand\plotb{plot[smooth,domain=-1:4,samples=100]({.8*sin(\x*5 r)+2},\x)}
\begin{document}
\begin{tikzpicture}
  \begin{scope}
    \draw[clip, preaction={draw, ultra thick, double distance=0pt}]
    plot[smooth cycle]
    coordinates{(0,2) (2.2,2.2) (3.1,3.3) (6,3) (6,0) (0,0)};
    \path[name path=a] \plota;
    % second path (b)
    \path[name path=b]\plotb;
    % current bounding box (boundaries)
    \path[name path=boundaries]
    (current bounding box.south west)
    rectangle
    (current bounding box.north east);
    % two intersestion for each path (ai-1,ai-2) and (bi-1,bi-2)
    \path[name intersections={of=a and boundaries,name=ai}];
    \path[name intersections={of=b and boundaries,name=bi}];
    \foreach \regcol/\pta/\ptb in {%
      red/north/east,% north of path a and east of path b
      green/north/west,% north of path a and west of path b
      yellow/south/east,% ...
      blue/south/west% ...
    }{
      \begin{scope}
        % clipping region path a
        \clip \plota |- (current bounding box.\pta) -| (ai-1);
        % clipping region path b
        \clip \plotb -| (current bounding box.\ptb) |- (bi-1);
        \fill[\regcol]
        (current bounding box.south west)
        rectangle
        (current bounding box.north east);
      \end{scope}
    }
    % drawing pathes
    \draw \plota;
    \draw \plotb;
  \end{scope}
  % uncomment to show paths
  %\draw[dashed] \plota;
  %\draw[dashed] \plotb;
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
This is great, it is exactly what I was looking to do. –  Pascal Jun 26 '12 at 6:39
add comment

Here is a variant for a solution:

\begin{tikzpicture}
\draw[clip, preaction={draw, ultra thick, double distance=0pt}]
  plot[smooth cycle]
  coordinates{
   (0,2) (2.2,2.2) (3.1,3.3) (6,3) (6,0) (0,0)
  };

\draw[thick, draw=gridcolor, fill=red] (2,1) -- (2,4) -- (-2,1) -- cycle;
\draw[thick, draw=gridcolor, fill=blue] (2,1) -- (2,-4) -- (-2,1) -- cycle;
\draw[thick, draw=gridcolor, fill=yellow] (2,1) -- (2,-4) -- (10,1) -- cycle;
\draw[thick, draw=gridcolor, fill=green] (2,1) -- (2,6) -- (10,1) -- cycle;
\end{tikzpicture}

I used clip to trim everything outside the curve you specified. the line of the clipping path is also 'cut in half', that's why I used the hack with double. The command now actually draws two identical paths offset just with the half of the line width. (You can experiment by omitting double distance=0pt altogether or by specifying a different offset distance.) In addition this has to be performed as a preaction, since clip does not like any additional options that modify the path.

Then you just have to draw the patchwork of colored partitions, of arbitrary size, as usual, only the part within the clipped path will be visible anyway.

EDIT: Btw, if you do not close the partition paths with cycle, the lines themselves will also be colored the same color as the fill.

enter image description here

share|improve this answer
    
This is really neat. What if the partitionning lines were also curvy (for instance if I changed the first coordinates to {(2,2.2) (1.8,1.3) (2,0)}), would there still be a way? –  Pascal Jun 23 '12 at 19:30
    
I don't think that makes any difference (if I understand correctly). You can partition your area in any fashion you like. It might be easier if you first color all the area that remains visible after clipping with a given color and then add the other patches: \draw[fill=blue] (-1,-1) rectangle (10,10); \draw[thick, draw=gridcolor, fill=red] plot[smooth cycle]coordinates{(2,4) (2,2.2) (1.8,1.3) (2,0) (2,-1) (10,-1) (10,4)}; –  Count Zero Jun 23 '12 at 19:55
    
Smart solution. –  percusse Jun 23 '12 at 21:59
    
I was meaning if you had more than one dividing smoothed line (because the clipping trick doesn't seem to work anymore). Maybe there is a way to define overlapping zones and then color them (which would make the trick work)? –  Pascal Jun 24 '12 at 6:36
    
@Pascal: I'm not sure I can follow you. Replacing the straight lines with any kind of closed path works fine with me. Can you edit your question and add some more information? –  Count Zero Jun 24 '12 at 10:56
show 1 more comment

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.