TransWikia.com

Intersection of 2 lines not really connected in TikZ

TeX - LaTeX Asked by cacamailg on March 13, 2021

In the code below I repeat one line (one with opacity=0 and other without it) in order to draw the intersection of 2 lines that are not connected. I am seeking a better way to achieve the same result. Using arc would also be a possible solution.

documentclass[tikz]{standalone}
usetikzlibrary{intersections,backgrounds}

begin{document}

begin{tikzpicture}

begin{pgfonlayer}{background}
draw[fill=yellow] (0.25,0.5) rectangle (1.75,1.5);
end{pgfonlayer}
draw [name path=a, opacity=0] (0,0) -- (2,2);% line that will be repeated
draw [name path=b] (0,2) -- (2,0);
path [name intersections={of=a and b,by=inter}];

filldraw [yellow] (inter) circle (2pt);
draw (0,0) -- (2,2);% line repeated

end{tikzpicture}
end{document}

Note: I only want to improve the way intersection between two lines is drawn, but keep the current aspect in the intersection of lines and rectangle. Moreover, the rectangle is not empty.

enter image description here

4 Answers

OK, quick and dirty, so not sure how robust this is, but by using the calc library (section 13.5 "Coordinate Calculations" in the 2.10 PGF Manual) and tying things up using the style args key handle (section 55.4.4 "Defining Styles"), it at least goes part of the way to showing how it could be done.

documentclass[tikz]{standalone}
usetikzlibrary{intersections,backgrounds}
usetikzlibrary{calc}
begin{document}

begin{tikzpicture}
tikzset{
    connect/.style args={(#1) to (#2) over (#3) by #4}{
        insert path={
            let p1=($(#1)-(#3)$), n1={veclen(x1,y1)}, 
            n2={atan2(y1,x1)}, n3={abs(#4)}, n4={#4>0 ?180:-180}  in 
            (#1) -- ($(#1)!n1-n3!(#3)$) 
            arc (n2:n2+n4:n3) -- (#2)
        }
    },
}
begin{pgfonlayer}{background}
draw[fill=yellow] (0.25,0.5) rectangle (1.75,1.5);
end{pgfonlayer}

draw [name path=a] (0,0) -- (2,2);
path [name path=b] (0,2) coordinate (x)  -- (2,0) coordinate (y);
path [name intersections={of=a and b,by=inter}];

draw [red, ultra thick, connect=(x) to (y) over (inter) by -6pt];
draw [connect=(x) to (y) over (inter) by 3pt];

end{tikzpicture}
end{document}

enter image description here

In fact, we could go further and tie a lot of stuff up in the connect style. This involves the use of pgfextra (section 14.18 "The PGF-Extra Operation") and the pgfinterruptpath environment (section 69.3.2 "Graphic Scope Environments").

documentclass[tikz]{standalone}
usetikzlibrary{intersections,backgrounds}
usetikzlibrary{calc}
begin{document}

begin{tikzpicture}
tikzset{
    connect/.style args={(#1) to (#2) over (#3) to (#4) by #5}{
        insert path={
            pgfextra{
                pgfinterruptpath
                    path [name path=a] (#1) -- (#2);
                    path [name path=b] (#3) -- (#4);
                    path [name intersections={of=a and b,by=inter}];
                endpgfinterruptpath                
            }
            let p1=($(#1)-(inter)$), n1={veclen(x1,y1)}, 
                            n2={atan2(y1,x1)}, n3={abs(#5)}, n4={#5>0 ?180:-180}  in 
                            (#1) -- ($(#1)!n1-n3!(inter)$) 
                            arc (n2:n2+n4:n3) -- (#2)
        }
    },
}
begin{pgfonlayer}{background}
draw[fill=yellow] (0.25,0.5) rectangle (1.75,1.5);
end{pgfonlayer}

draw  (0,0) -- (2,2);

draw [red, very thick, connect={(0,2) to (2,0) over (0,0) to (2,2) by -5pt}];
draw [connect={(0,2) to (2,0) over (0,0) to (2,2) by 3pt}];

end{tikzpicture}
end{document}

The result is the same as before.

Correct answer by Mark Wibrow on March 13, 2021

Here I keep the Jake's answer to my beginning question, which might be useful for someone. For this to work, the rectangle shall be "empty" and not in background layer.

documentclass[tikz]{standalone}

begin{document}
begin{tikzpicture}

draw (0,0) -- (2,2);
draw [draw=white,double=black,double distance=pgflinewidth,ultra thick] (0,2) -- (2,0);
draw (0.25,0.5) rectangle (1.75,1.5);

end{tikzpicture}
end{document}

enter image description here

Answered by cacamailg on March 13, 2021

Although an awesome answer from Mark Wibrow, I like things to be more smooth, so I implemented controls to his code (it ends up reducing a bit of the calculations as well):

documentclass[tikz, border=5mm]{standalone}
usetikzlibrary{calc}
usetikzlibrary{intersections}

%%% Adapted from Mark Wibrow
tikzset{%
    connect/.style args={(#1) to (#2) over (#3) by #4}{%
        insert path={%
            let p1=($(#1)-(#3)$), n1={veclen(x1,y1)}, n2={abs(#4)}  in%
                (#1) --%
                ($(#1)!n1-n2!(#3)$) .. controls +(0:n2/2) and +(180:n2/2) ..%
                +(n2,#4)%
                .. controls +(0:n2/2) and +(180:n2/2) .. ($(#1)!n1+n2!(#3)$) -- (#2)%
        }%
    }%
}

begin{document}
begin{tikzpicture}[line join=round]
  coordinate (a) at (-0.5,0.5);
  coordinate (b) at (8,-0.5);
  draw[ultra thick, name path=sine, domain=-1:8, smooth, samples=50] plot (x,{sin(x r)});
  path[name path=line] (a) -- (b);
  path[name intersections={of=sine and line}];
  draw[blue, connect={(a) to ($(a)!.5!(intersection-2)$) over (intersection-1) by 12pt},
        connect={($(a)!.5!(intersection-2)$) to ($(intersection-2)!.5!(intersection-3)$) over (intersection-2) by -8pt},
        connect={($(intersection-2)!.5!(intersection-3)$) to (b) over (intersection-3) by 4pt}
        ];
end{tikzpicture}
end{document}

enter image description here

Answered by Guilherme Zanotelli on March 13, 2021

Here's a solution using the spath3 package (development version at github). This package introduces the ability to split a path where it intersects with another path (or itself), to insert gaps, and to splice in other paths (such as arcs). So we do the following:

  1. Save the two paths.
  2. Split the over path where it crosses the under path.
  3. Insert a decent sized gap at that point.
  4. Splice in an arc into that gap.
  5. Now split the under path where it crosses under this new version of the over path.
  6. Insert a small gap at that point.

Since the gaps are genuine, there's no problem with the background path. If there's a possibility that the arc might be upside down then the development version contains a version of the splicing code that ensures that the arc is always the right way up.

Here's the result:

Like a bridge over a troubled crossing

documentclass{article}
%url{https://tex.stackexchange.com/q/111660/86}
usepackage{tikz}
usetikzlibrary{
  spath3,
  intersections,
  backgrounds
}

begin{document}

begin{tikzpicture}

begin{pgfonlayer}{background}
draw[fill=yellow] (0.25,0.5) rectangle (1.75,1.5);
end{pgfonlayer}
path [spath/save=a] (0,0) -- (2,2);% line that will be repeated
path [spath/save=b] (0,2) -- (2,0);

path[spath/save=arc] (0,0) arc[radius=1cm, start angle=180, delta angle=-180];

tikzset{
  spath/split at intersections with={b}{a},
  spath/insert gaps after components={b}{8pt},
  spath/join components with={b}{arc},
  spath/split at intersections with={a}{b},
  spath/insert gaps after components={a}{4pt},
}

draw[spath/use=a];
draw[spath/use=b];

end{tikzpicture}
end{document}

Answered by Andrew Stacey on March 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP