[Tex/LaTex] Draw only some segments of a path in TikZ

diagramstikz-pgf

Is there a good way to create a path in TikZ only some segments of which are stroked? I want to create the whole path in a single command so that it can be filled, but I also want to stroke some parts of the boundary of the filled region, but not all of them. The best solution I've thought of so far is to use edge operations in the middle of the path to do the stroking; for instance here is a green-filled square with one edge stroked:

\path[fill=green] (0,0) -- (1,0) edge (1,1) -- (1,1) -- (0,1) -- cycle;

This is a little better than

\path[fill=green] (0,0) -- (1,0) -- (1,1) -- (0,1) -- cycle;
\draw (1,0) -- (1,1);

but it still requires giving the command that draws the segment from (1,0) to (1,1) twice, which is annoying and error-prone if it's a more complicated command like a Bézier curve, and impossible if it's something like a circular arc that can't be drawn by a edge command (at least, not without writing a custom "to path"). Any suggestions?

Best Answer

This is a reworking of Jan's code to make it a little more TikZ-like. It still does the same thing: repeats the path, once as a fill and once as a draw, but with certain parts of the path removed for the draw stage. The main modification is that (hopefully) it now looks exactly like a standard TikZ command.

\documentclass{article}

\usepackage{tikz}
\makeatletter
\long\def\my@drawfill#1#2;{%
\@skipfalse
\fill[#1,draw=none] #2;
\@skiptrue
\draw[#1,fill=none] #2;
}

\newif\if@skip

\newcommand{\skipit}[1]{%
\if@skip
\else
#1
\fi
}

\newcommand{\drawfill}[1][]{%
  \my@drawfill{#1}}
\makeatother



\begin{document}
\begin{tikzpicture}
  \drawfill[fill=green,draw=blue,ultra thick] (0,0) -- (0,1) \skipit{--} (1,1) -- (1,0) \skipit{.. controls +(0,-1) and +(0,-1) ..} (0,0);
\end{tikzpicture}
\end{document}

This produces:

alt text

I'm sure that there are additional improvements to be made, which is one reason why I'm making this community wiki (the other being that it is really Jan's answer). In particular:

  1. I couldn't make the \skipit command take an optional argument and still work. I think that it doesn't get expanded properly before the genuine TikZ commands see it and they don't like having macros as part of their path specification.

  2. The assignment of key-value pairs is a bit of a hack: basically, we turn off the drawing on the fill command and turn off the filling on the draw command. It might be useful to be able to specify a set of keys that only get put on the draw command and a set for the fill command, so something like \drawfill[options for both, fillopt={options for fill}, drawopt={options for draw}] but I don't know enough (anything) about pgfkeys so don't have a clue how to go about that.