4

Sorry, I am fairly new to TikZ.

Is there a set-theory way of cutting, intersecting, unifying paths like in (proprietary) GUI applications? Or better asked, what is the tikz approach to to deal with that problem? Let's say I've built several paths, in GUI-land I would select two of them and do an operation resulting in a new path. But how do I define a reusable tikz-path in the first place without drawing it right away? (A link to a systematic macro-tutorial would be very much appreciated.)

There are a lot of snippets out there, but for a beginner it`s all quite confusing. There are pics and shapes and macros and so on, but in the end there are just paths. Do I really have to start studying the underlying layers?

Here is a real world problem:

\documentclass[tikz,border=0.2cm]{standalone}
\usetikzlibrary{scopes}
\begin{document}
\begin{tikzpicture}[scale=4]
    %\draw [help lines,step=0.1] (-0.2,-0.8) grid (1,0.8);
    \path [fill=gray!50] (-0.2,-0.8) rectangle (1,0.8);
    \begin{scope} %[every path/.style={fill=white}]
        \draw (0,-0.65) --
            ++(0  , 0.3) .. controls +( 0.25,0) and +(-0.5,0) ..
            ++(0.8, 0.7) --
            ++(0  ,-0.3) .. controls +(-0.25,0) and +( 0.5,0) ..
            cycle;
        \draw (0,-0.15) rectangle +(0.8,0.3);
        \draw (0, 0.65)  -- %%% Yes is is the path from above flipped over. I just couldn't figure out how to do it properly
            ++(0  ,-0.3) .. controls +( 0.25,0) and +(-0.5,0) ..
            ++(0.8,-0.7) -- 
            ++(0  , 0.3) .. controls +(-0.25,0) and +( 0.5,0) ..
            cycle;
    \end{scope}
\end{tikzpicture}
\end{document}

Step by step procedure:

  1. Create 3 paths: "rising bent rectange", "bar", "falling bent rectangle"

intermediate step

  1. Select "bar" and "rising" paths.

start

  1. Cut "bar" from "rising" path.

1st step

  1. Select resulting paths and "falling" path.

2nd step

  1. Cut "falling" from other paths.

3rd step

  1. Select "bar" and "falling" path.

4th step

  1. Cut "falling" from "bar".

enter image description here

  1. Select resulting paths and "falling". ("rising" and "bar" can be discarded now)

enter image description here

  1. Cut through the background (using the 3 original paths maybe)

enter image description here

  1. Final result:

enter image description here

and without the grid in the back

final result

  • It's not clear to me what your desired outcome is. The second image can be obtained simply by drawing your paths in the correct order (lowest to highest). "Cutting out to see through" can be done using clipping. That said, cutting, splicing, and re-using paths can be done easily with my spath3 TikZ library. I'll add an example below using your code, but as I'm not sure what you're after then it might not be what you're actually after. – Andrew Stacey Feb 26 '21 at 18:52

2 Answers2

3

Here's an example using my spath3 library that can be used to split and recombine paths. I'm not very clear what your desired outcome is, so this is intended just as a start to help figure that out.

Firstly, I take your primary path (the curve) and use it to construct the curved region, resaving that as a path. Then I intersect that against itself (but flipped) to split the two paths into segments. Finally, I draw certain of those segments to create the outer region.

\documentclass[tikz,border=0.2cm]{standalone}
%\url{https://tex.stackexchange.com/q/585037/86}
\usetikzlibrary{scopes,spath3,intersections}
\begin{document}
\begin{tikzpicture}[scale=4]
    %\draw [help lines,step=0.2] (-0.2,-0.8) grid (1,0.8);
    \path [fill=gray!50] (-0.2,-0.8) rectangle (1,0.8);
\begin{scope} %[every path/.style={fill=white}]
\path[spath/save=curve] (0,-0.35) .. controls +( 0.25,0) and +(-0.5,0) .. ++(0.8, 0.7);

\path [ spath/save=lower path, spath/use=curve ] -- ++(0,-.3) [ spath/use={curve,move,weld,transform={scale=-1}} ] -- cycle; \path[spath/save=rectangle] (0,-0.15) rectangle +(0.8,0.3);

\tikzset{ spath/clone={upper path}{lower path}, spath/transform={upper path}{yscale=-1}, spath/split at intersections={upper path}{lower path}, spath/get components of={upper path}\Ucpts, spath/get components of={lower path}\Lcpts, }

\draw[ spath/use=\getComponentOf\Ucpts{3}, spath/use=\getComponentOf\Ucpts{4}, spath/use=\getComponentOf\Lcpts{3}, spath/use=\getComponentOf\Lcpts{4}, spath/use=\getComponentOf\Ucpts{6}, spath/use=\getComponentOf\Lcpts{6}, ]; \end{scope} \end{tikzpicture} \end{document}

Result:

Split and recombined paths

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • 1
    Note: in answering this question I discovered a minor bug in the spath3 library that is relevant for the cycle part. I've fixed it and will upload it to github (https://github.com/loopspace/spath3) shortly, and after it's been tested I'll upload it to ctan. – Andrew Stacey Feb 26 '21 at 19:54
  • Thanks for your effort. I had a quick look at your library but I'm getting too exhausted for today. I really ought to have a nap first. I'll be back tomorrow. –  Feb 26 '21 at 20:44
  • Sorry for the delay, I hope you didn't loos interest. This all looks very promissing. I've edited my question adding the step by step procedure. I've got your latest library from github but the picure I get looks different from what you've posted. –  Feb 27 '21 at 11:04
  • That might be because I've fixed the bug I referred to above and it means that the component numbers are different. To be honest, what you describe in the post is easiest to achieve by using clipping paths rather than splitting and recombining. I'll edit this post later today to show how that would work. – Andrew Stacey Feb 27 '21 at 11:14
2

Here's an answer to show what is possible using just clipping. I do use my spath3 library to construct the paths and to re-use them, but you could do away with that by just cutting-and-pasting.

\documentclass[tikz,border=0.2cm]{standalone}
%\url{https://tex.stackexchange.com/q/585037/86}
\usetikzlibrary{scopes,spath3,intersections,patterns}

\begin{document} \begin{tikzpicture}[scale=4] %\draw [help lines,step=0.2] (-0.2,-0.8) grid (1,0.8); \begin{scope} %[every path/.style={fill=white}] \path[spath/save=curve] (0,-0.35) .. controls +( 0.25,0) and +(-0.5,0) .. ++(0.8, 0.7);

\path [ spath/save=lower path, spath/use=curve, ] -- ++(0,-.3) [ spath/use={curve,move,weld,transform={scale=-1}}, ] -- cycle;

\path[spath/save=rectangle] (0,-0.15) rectangle +(0.8,0.3);

\tikzset{ spath/clone={upper path}{lower path}, spath/transform={upper path}{yscale=-1}, }

\path[preaction={fill=red!50!white},pattern=bricks, pattern color=white] (-0.2,-0.8) rectangle (1,0.8);

\begin{scope}[even odd rule] \clip (-0.2,-0.8) rectangle (1,0.8) [spath/use=upper path]; \begin{scope}[even odd rule] \clip (-0.2,-0.8) rectangle (1,0.8) [spath/use=rectangle]; \begin{scope}[even odd rule] \clip (-0.2,-0.8) rectangle (1,0.8) [spath/use=lower path]; \path [fill=gray!50] (-0.2,-0.8) rectangle (1,0.8); \end{scope} \draw[spath/use=lower path]; \end{scope} \draw[spath/use=rectangle]; \end{scope} \draw[spath/use=upper path];

\end{scope} \end{tikzpicture} \end{document}

I've put the pattern in to show that you really are seeing through the paths and not filling them in white.

Clipping against paths

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • I definitely want to avoid copy-paste. –  Feb 27 '21 at 14:57
  • Yes, this is exactly what I looking for. Clipping with even-odd rule does the trick. Thanks a lot. –  Feb 27 '21 at 15:01
  • I'll try to learn to use your library. I think it makes tikz-code cleaner and easier to maintain. I'm trying to avoid dupliation, because usually I have to make smaller changes later on and it's a real pain to find all the copies especially after a week or so. I (will) try to use coordinates, defs and macros as much as possible but having a named path that can be copied and transformed is usually just what's needed. Any ideas how to make groups of paths? –  Feb 27 '21 at 15:28
  • What do you mean by a "group of paths"? You can create a list of paths in some fashion, something like \def\GroupOfPaths{{abc}{def}{ghi}}. Or you can just have a single path with multiple components. It depends slightly on what you intend to do with it. – Andrew Stacey Feb 27 '21 at 19:46
  • Let's say we have finished drawing something made out of many paths. And now we want several instances of it in our picture but in variouse sizes, rotated in different directions or flipped over ... you name it. Then it would come in handy to handle it as a single object that can be cloned and transformed. –  Feb 27 '21 at 21:47
  • That sounds very like a pic. – Andrew Stacey Feb 28 '21 at 00:14