1

I'm trying to draw a block diagram with tikz and would like to match some kind of convention concerning the intersection of lines/paths. The convention says, that the marking/semicircle has to be at the line that is running vertically. For that I edited a command overlap to my needs. Using \overlap{master path}{slave path} the slave path will get a semicircle at the intersection with the master path.

In my MWE the command works but can't distinguish if master/slave line runs horizontally or vertically at the intersection.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,positioning}
\usetikzlibrary{arrows}
\usetikzlibrary{intersections}
%
\usepackage{tkz-euclide}
%
\newcommand{\overlap}[2]{
    \path[name intersections={of= #1 and #2,sort by=#2, name=punkt, total=\t},/utils/exec={\global\let\t=\t}];
    \ifnum \t>0
    \foreach \s in {1,...,\t}{          
        % circle for intersections
        \path[name path global/.expanded =whitecirc-\s,draw=none,line width=0pt]
        (punkt-\s)circle(5.6705pt);
    % name intersections
    \path[name intersections={of=#2 and whitecirc-\s,sort by=#2,name=wb,total=\numwb},
    /utils/exec={\global\let\numwb=\numwb}];
    \ifnum \numwb>1

    % inner white circle
    \path[draw=white,fill=white, line width=0.2pt]
    (punkt-\s)circle(5.35pt); 

    % intersections if circle with other line
    \path[name intersections={of=#1 and whitecirc-\s,sort by=#2,name=wa}];

    % re-draw 2nd line (slave path)
    \draw[shorten <=-2pt,shorten >=-2pt](wa-1.center)--(wa-2.center);

    % draw arc
    \coordinate (A) at (wb-2);
    \coordinate (B) at (wb-1);
    \tkzInterCC[R](A,2.4mm)(B,2.4mm)
    \tkzGetPoints{X}{Y}
    \coordinate (Z) at ($(X)!0.5!(Y)$);

    % thicker white arc for hiding small part of slave path
    \tkzDrawArc[color=white,ultra thick, line cap=butt,shorten <=0.4pt,shorten >=0.4pt](Z,B)(A)
    % normal Arc (master path)
    \tkzDrawArc[color=black,line cap=butt](Z,B)(A)
    \fi
}
\fi

} % \begin{document} % \begin{tikzpicture}[scale=1.0,>=latex'] \draw[fill=white] (0,0) rectangle (6,9); % \foreach \i in {3,4,5} { \coordinate (w\i) at (1,\i); \coordinate (e\i) at (5,\i); \draw[->,name path=path\i] (w\i) --(e\i); } % \foreach \i in {1,2,6,7,8} { \node[circle,draw,align=center,fill=black,inner sep=0pt, minimum size = 3pt] (w\i) at(1,\i) {}; } % \coordinate (h1) at ($(w3)!0.4!(e3)$);\coordinate (h2) at ($(w3)!0.6!(e3)$); \draw[->,name path=path2] (w2) -| (4,6) |- (2,6) |- (1,8); \draw[->,name path=path1] (w1) -| (3,5) |- (w7); % \overlap{path2}{path1} \overlap{path3}{path1} \overlap{path4}{path1} \overlap{path5}{path1} % \overlap{path3}{path2} \overlap{path4}{path2} \overlap{path5}{path2} % \node [draw,fill=red,fill opacity=0.4,rectangle,minimum size=1cm,anchor=center] at (2,7) {}; % \end{tikzpicture} \end{document}

No distinction between vertical and horizontal master/slave segments

Overall I don't know if there is a more clever way to redraw intersections automatically. Naming every path let's say path1,path2,path3,...,pathN and searching for every intersection within 2 \foreach-loops could be an approach.

\foreach \x in {1,2,3,4} 
\foreach \y in {2,3,4,5} 
    {
        \if\ifnum\x>\y T\else\ifnum\x=\y T\else F\fi\fi T%
        %  TRUE
        \break foreach
        \else
        %  FALSE
        \overlap{path\y}{path\x};
        \fi
    }

But using this loop leads to another problem which let's the circle flip randomly. Flipped semicircle while using foreach-loop

Nivek
  • 115

1 Answers1

1

There are several ways such as using shorten, postaction after knowing intersection points.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[>=stealth]
\def\r{.35}
\draw[fill=pink] (-1,-1) rectangle (1,1);

\draw[<-] (-2,0)--(-\r,0) arc(180:0:\r)--(2,0) --++(-90:2-\r) arc(90:-90:\r)--++(-90:1-\r); \fill[pink] (0,\r) circle(2pt);
\fill[white] (2+\r,-2) circle(2pt); \draw[<-] (-2,2)--++(0:2)--++(-90:4)--++(0:4)--++(-90:1); \end{tikzpicture}
\end{document}

Black Mild
  • 17,569
  • Well, doing it manually works fine. But since my actual block diagram has a bigger number of lines and intersections, an automated way of achieving this would be great. I don't know how to use the shorten for that since it can only handle to shorten the path in the direction of end or start point. Using postaction seems legit but I want to re-draw the intersections after all paths are drawn. – Nivek Nov 10 '20 at 14:30
  • @Nivek In case you diagram has a bigger number of lines and intersections, then you cam make a \newcommand to shorten your code. Please see more here https://tex.stackexchange.com/questions/570233/intersect-two-lines/570270#570270 and here https://tex.stackexchange.com/questions/334483/decorate-path-precisely-on-intersections-with-tikz-avoiding-crossing-lines – Black Mild Nov 10 '20 at 16:10