8

I'm using the technique from this TeX.SO answer to produce a circuit with a crossing (I'm using Beamer because in the next step I'll use that to set a background image)

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{intersections}
\usetikzlibrary{calc}

\usepackage{circuitikz}

\newlength{\crossing}
\makeatletter
\setlength{\crossing}{\ctikzvalof{bipoles/crossing/size}\pgf@circ@Rlen}
\makeatother

\begin{document}

\begin{frame}
\begin{tikzpicture}[scale=4,transform shape]
    \draw[name path=p1] (0,0) circle -- (2,0) circle;
    \draw[name path=p2] (1,1) circle -- (1,-1) circle;

    \path [name intersections={of=p1 and p2,by=cross}]
          [fill=white] (cross) circle[radius=0.5\crossing];
    \path (cross) node[jump crossing,rotate=-90]{};
\end{tikzpicture}
\end{frame}

\end{document}

enter image description here

This works as long as the background is white. However, if the background is not white, but some arbitrary image, it becomes apparent that the crossing-over discontinuity was achieved not by erasure, but by filling with white:

\usebackgroundtemplate{%
\tikz\node[opacity=0.1] {\includegraphics[height=\paperheight,width=\paperwidth]{example-grid-100x100pt}};}

enter image description here

So I thought I should apply this technique and put everything in a knockout group:

\begin{tikzpicture}[scale=4,transform shape]
  \begin{scope}[transparency group=knockout]
    \draw[name path=p1] (0,0) circle -- (2,0) circle;
    \draw[name path=p2] (1,1) circle -- (1,-1) circle;

    \path [name intersections={of=p1 and p2,by=cross}]
          [fill,opacity=0] (cross) circle[radius=0.5\crossing];
    \path (cross) node[jump crossing,rotate=-90]{};
\end{scope}
\end{tikzpicture}

But now the circle that's supposed to clear the intersection doesn't seem to do anything:

enter image description here

What am I doing wrong, how do I achieve my desired result?

8
  • @Qrrbrbirlbel but that means I have to split the drawing of the (1,1) -- (1,-1) edge into two commands, which are apart from each other by the drawing of the crossing... that is going to decrease maintainability.
    – Cactus
    Commented Sep 26, 2022 at 17:11
  • Have you tried another PDF viewer? As the linked answer says, this is viewer dependent. The linked answer doesn't work for me, either. Commented Sep 26, 2022 at 17:13
  • If you look at the code of the jump crossing, in pgfcircshapes.tex, around line 618, you can see that the broken "node" is obtained by just drawing two segments. FWIK, there is no way to "unpath" a path once is drawn; @Qrrbrbirlbel comment is the way to. Maybe you can embed the thing in a macro.
    – Rmano
    Commented Sep 26, 2022 at 17:30
  • 1
    Another question: what is the idea with \draw (0,0) circle -- (2,0) circle;? What are the circles doing there?
    – Rmano
    Commented Sep 26, 2022 at 17:34
  • 1
    @rmano oh that's just there I guess because my original code had some shapes at the path endpoints and I didn't remove them correctly when minimizing...
    – Cactus
    Commented Sep 26, 2022 at 17:35

5 Answers 5

5

You could wrap the circuit before the colored background picture in a transparency group and add the option blend mode=multiply. This, however, will only look nice if the drawing in the front is purely black:

\documentclass{beamer}
\usepackage{circuitikz}
\usetikzlibrary{intersections}
\usetikzlibrary{calc}

\usebackgroundtemplate{%
\tikz\node[opacity=0.1] {\includegraphics[height=\paperheight, width=\paperwidth]{example-grid-100x100pt}};}
    
\newlength{\crossing}
\makeatletter
\setlength{\crossing}{\ctikzvalof{bipoles/crossing/size}\pgf@circ@Rlen}
\makeatother

\begin{document}

\begin{frame}
\begin{tikzpicture}[scale=4, transform shape]
    \begin{scope}[transparency group, blend mode=multiply]
        \draw[name path=p1] (0,0) -- (2,0);
        \draw[name path=p2] (1,1)-- (1,-1);

        \path [name intersections={of=p1 and p2, by=cross}]
              [fill=white] (cross) circle[radius=0.5\crossing];
        \path (cross) node[jump crossing, rotate=-90]{};
    \end{scope}
\end{tikzpicture}
\end{frame}

\end{document}

enter image description here

1
  • I'm accepting this one for now as this is the least disruptive to the structure of the actual figure.
    – Cactus
    Commented Sep 27, 2022 at 10:01
6

Yet an other solution. -you can make everything that is white transparent by using tikzfadingfrompicture like this:

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{fadings, backgrounds, intersections}
\usepackage{circuitikz}

\newlength{\crossing}
\makeatletter
\setlength{\crossing}{\ctikzvalof{bipoles/crossing/size}\pgf@circ@Rlen}
\makeatother

\begin{tikzfadingfrompicture}[name=myfading, background rectangle/.style={fill=transparent!0}, show background rectangle, scale=4, transform shape]
\draw[name path=p1] (0,0) -- (2,0);
\draw[name path=p2] (1,1) -- (1,-1);
\path [name intersections={of=p1 and p2, by=cross}]
[fill=white] (cross) circle[radius=0.5\crossing];
\path (cross) node[jump crossing, rotate=-90]{};
\coordinate (sw) at (current bounding box.south west);
\coordinate (ne) at (current bounding box.north east);
\path (0,0) circle[radius=10]; %encompassing circle for alignment
\end{tikzfadingfrompicture}

\begin{tikzfadingfrompicture}[name=myinvfading]
\fill[transparent!0] (0,0) (sw) rectangle (ne);
\fill[path fading=myfading, fit fading=false, transparent!100] (sw) rectangle (ne);
\path (0,0) circle[radius=10]; %encompassing circle for alignment
\end{tikzfadingfrompicture}

\begin{document}
\begin{tikzpicture}
\node[opacity=0.2] at (4,0) {\includegraphics{example-grid-100x100pt}};
\fill[path fading=myinvfading, fit fading=false]  (sw) rectangle (ne);
\end{tikzpicture}
\end{document}

Lines with a crossing symbol on top of a picture

Edit:

The solution uses two colors transparent!0(white) and transparent!100(black).

  • In myfading the background is transparent!0 (or white for the filled node) and everything is drawn normally on this background.

  • In myinvfading the background is transparent!0 and myfading is inserted with the color transparent!100. This inverts the colors, and we are now back to the original colors.

  • Now myinvfading can be draw black in the tikzpicture as the final result.

3
  • "you can make everything that is white transparent" This would be a terrific solution to my problem! Unfortunately, the code you show seems to be much more complicated than that -- the intro makes it sound like I can just put something on my tikzpicture to handle white as transparent, but then you seem to be drawing in multiple passes... can you expand your answer with explaining what's going on there?
    – Cactus
    Commented Sep 27, 2022 at 10:00
  • 1
    "much more complicated than that" - Much more complicated than what? The solution is not simple. I would not use it - it is a hack that kind of patches an other hack (filling an area with white to cover some unwanted lines and hope these lines align with the cover nodes lines). I will add some explaning text. Commented Sep 27, 2022 at 10:06
  • I meant it's much more complicated than just telling TikZ to regard all white as transparent :)
    – Cactus
    Commented Sep 27, 2022 at 10:19
3

I find it a bit on the convoluted side, but... you can find the point by using paths instead of draws, do an inverse clip in a scope (adapted from here), re-draw the lines, exit the scope, and add the jump crossing:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{intersections}
\usetikzlibrary{calc}
\usebackgroundtemplate{%
\tikz\node[opacity=0.1] {\includegraphics[height=\paperheight,width=\paperwidth]{example-grid-100x100pt}};}
\usepackage{circuitikz}

\newlength{\crossing}
\makeatletter
\setlength{\crossing}{\ctikzvalof{bipoles/crossing/size}\pgf@circ@Rlen}
\makeatother
\tikzset{
    clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey 
    invclip/.style={
        clip,insert path=
            [clip even odd rule]{
                [reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
            }
    }
}
\begin{document}

\begin{frame}
\begin{tikzpicture}[scale=4,transform shape]
    \path[name path=p1] (0,0)  -- (2,0) ;
    \path[name path=p2] (1,1) -- (1,-1) ;
    \begin{scope}[overlay]
        \path [name intersections={of=p1 and p2,by=cross}];
        \clip [invclip]
            (cross) circle[radius=0.5\crossing];
        \draw (0,0)  -- (2,0) ;
        \draw (1,1) -- (1,-1) ;
    \end{scope}
    \path (cross) node[jump crossing,rotate=-90]{};
\end{tikzpicture}
\end{frame}

\end{document}

enter image description here

(okular is struggling with the antialiasing here a bit...)

3
  • Notice the correction due to tex.stackexchange.com/a/290508/38080, but well, you got the idea
    – Rmano
    Commented Sep 26, 2022 at 18:02
  • Thanks @Qrrbrbirlbel, adjusted
    – Rmano
    Commented Sep 26, 2022 at 18:07
  • 1
    This can be improved a bit by save path-ing p1 and p2 and then \draw-ing them with use path, to avoid specifying the same path details twice.
    – Cactus
    Commented Sep 26, 2022 at 20:59
1

As I said in the comments and the linked answer, the knockout method is viewer dependent.

Below, I've implemented a crossings over=<a>--<b> over {<c1>--<d1>, …, <cn>--<dn>} that will draw a line from <a> to <b> crossing all given lines. The order is important!

The values crossing over radius and crossing over clearance change the outcome of that little arc.

The key crossing over style with either paramater multiply or knockout must be used at an encompassing scope.

Code

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc}
\usebackgroundtemplate{%
  \tikz\node[inner sep=+0pt,opacity=0.1]
    {\includegraphics[height=\paperheight,width=\paperwidth]{example-grid-100x100pt}};}
\tikzset{
  crossing over radius/.initial=.4mm,
  crossing over clearance/.initial=3*\the\pgflinewidth,
  @@crossings over/.style n args={3}{
    @@@crossings over/.style args={##1--##2}{
      @crossing over={#1}{#2}{##1}{##2}},
    @@@crossings over/.list={#3}},
  crossings over/.style args={#1--#2 over #3}{
    insert path={
      coordinate (@after@intersect@) at (#1)
      let \p{@diff@}=($(#1)-(#2)$),
          \n{@diff@}={atan2(\y{@diff@},\x{@diff@})} in
      (#1)[@@crossings over={#1}{#2}{#3}] -- (#2)}},
  @crossing over/.style n args={4}{
    insert path={
      -- ($(intersection of #1--#2 and #3--#4)!\pgfkeysvalueof{/tikz/crossing over radius}!(#1)$)
      coordinate (@before@intersect@)
      \pgfextra\pgfinterruptpath
        \draw[@crossing over style, line width=\pgfkeysvalueof{/tikz/crossing over clearance}]
          (@before@intersect@)
            arc[start angle=\n{@diff@}, delta angle=-180, radius=\pgfkeysvalueof{/tikz/crossing over radius}];
      \endpgfinterruptpath\endpgfextra
      arc[start angle=\n{@diff@}, delta angle=-180, radius=\pgfkeysvalueof{/tikz/crossing over radius}]}},
  crossing over style/.is choice,
  @crossing over style/.code=%
    \tikzerror{You need to use "crossing over style" with option "multiply" or "knockout"},
  crossing over style/multiply/.style={
    @crossing over style/.style={draw=white},
    transparency group, blend mode=multiply},
  crossing over style/knockout/.style={
    @crossing over style/.style={draw=white,opacity=0},
    transparency group=knockout}}
\newcommand*\myPicture[1]{%
    \begin{tikzpicture}[scale=4, transform shape, #1]
    \coordinate (A) at (0,0) coordinate (B) at (2,0)
     coordinate (C) at (1,1) coordinate (D) at (1,-1)
     coordinate (E) at (0,1) coordinate (F) at (2, -.4)
     coordinate (G) at (1.5,.5) coordinate (H) at (-.5,1);
    \draw (A) -- (B);
    \draw [crossings over=C--D over A--B];
    \draw[green] [crossings over=E--F over {C--D, A--B}];
    \draw[red] [crossings over=G--H over {C--D, E--F}];
    \end{tikzpicture}}

\begin{document}

% \begin{frame}
% \myPicture{}% error
% \end{frame}

\begin{frame}
\myPicture{crossing over style=multiply}
\end{frame}

\begin{frame}
\myPicture{crossing over style=knockout}
\end{frame}
\end{document}

Output

Notice the different greens and reds.

multiply blend

enter image description here

knockout

enter image description here

0

Since my other answer is based on a very different approach, I will add this other solution that is based on the mechanics and tools provided by CircuiTikZ.

First of all, things are much easier if you use the jump crossing node provided by CircuiTikZ:

\documentclass{beamer}
\usepackage{circuitikz}

\usebackgroundtemplate{%
\tikz\node[opacity=0.1] {\includegraphics[height=\paperheight, width=\paperwidth]{example-grid-100x100pt}};}

\begin{document}

\begin{frame}
\begin{circuitikz}[scale=4, transform shape]
    \node at (1,0)[jump crossing, rotate=-90] (X) {};
    \draw (0,0) -- (X.south) (X.north) -- (2,0);
    \draw (1,1) -- (X.west) (X.east) -- (1,-1);
\end{circuitikz}
\end{frame}

\end{document}

But if you still want a solution based on bipoles (using to-paths as suggested in the CircuiTikZ manual), you can imitate this by defining a new custom bipole called crossing under which essentially draws a line with a small gap, exactly where the arc of the crossing bipole would sit:

\documentclass{beamer}
\usepackage{circuitikz}

\usebackgroundtemplate{%
\tikz\node[opacity=0.1] {\includegraphics[height=\paperheight, width=\paperwidth]{example-grid-100x100pt}};}

\makeatletter
\pgfcircdeclarebipole
{}
{\ctikzvalof{bipoles/crossing/size}}
{crossing under}
{\ctikzvalof{bipoles/crossing/size}}
{\ctikzvalof{bipoles/crossing/size}}{
    \pgfscope
        \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@zero}}
        \pgfpathlineto{\pgfpoint{0.4\pgf@circ@[email protected]}{\pgf@circ@res@zero}}
        \pgfpathmoveto{\pgfpoint{0.4\pgf@circ@res@right+.4pt}{\pgf@circ@res@zero}}
        \pgfpathlineto{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@zero}}
        \pgfusepath{draw}
    \endpgfscope
}
\pgfcirc@activate@bipole@simple{l}{crossing under}
\makeatother

\begin{document}

\begin{frame}
\begin{circuitikz}[scale=4, transform shape]
    \draw (0,0) to[crossing under] (2,0);
    \draw (1,1) to[crossing] (1,-1);
\end{circuitikz}
\end{frame}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .