I use TikZ to draw (undirected) graphs, but sometimes I would like to be able to mark where all the intersections/crossings are automatically. I understand that the TikZ intersections
library has the name intersections=
key, but this requires naming all the paths in my graph and then using that key for every pair of paths that intersect (and this is a real pain if I ever need to modify the graph because the pairs of edges that cross might change.) Naming all the paths manually also makes the code significantly less readable.
Q: Is there a way to do this automatically?
For example, here's an embedding of the Petersen graph in TikZ:
\documentclass{standalone}
\usepackage{tikz}
\tikzset{graph/.style={
every node/.style={circle,fill=black,inner sep=0pt,minimum width=8pt},
every path/.style={thick}
}}
\begin{document}
\begin{tikzpicture}[graph]
\foreach \i [evaluate=\i as \a using 90-(\i-1)*360/5] in {1,...,5} {
\node (o\i) at (\a:2) {};
\node (i\i) at (\a-36:0.7) {};
}
\draw (o1) -- (o2) -- (o3) -- (o4) -- (o5) -- (o1);
\draw (i1) -- (i2) -- (i3) -- (i4) -- (i5) -- (i1);
\draw (o1) -- (i3); \draw (o2) -- (i1); \draw (o5) -- (i5);
\draw[bend left] (o3) to (i4);
\draw[bend right] (o4) to (i2);
\end{tikzpicture}
\end{document}
There are two crossings in this embedding. Manually marking the crossings requires something like:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\tikzset{graph/.style={
every node/.style={circle,fill=black,inner sep=0pt,minimum width=8pt},
every path/.style={thick},
crossing/.style={rectangle,fill=red,inner sep=0pt,minimum size=4pt}
}}
\begin{document}
\begin{tikzpicture}[graph]
\foreach \i [evaluate=\i as \a using 90-(\i-1)*360/5] in {1,...,5} {
\node (o\i) at (\a:2) {};
\node (i\i) at (\a-36:0.7) {};
}
\draw (o1) -- (o2) -- (o3) -- (o4) -- (o5) -- (o1);
\draw[name path=p1] (i1) -- (i2) -- (i3) -- (i4) -- (i5) -- (i1);
\draw[name path=p2] (o1) -- (i3);
\draw (o2) -- (i1); \draw (o5) -- (i5);
\draw[name path=p3,bend left] (o3) to (i4);
\draw[name path=p4,bend right] (o4) to (i2);
\path [name intersections={of=p1 and p2}] (intersection-1) node[crossing] {};
\path [name intersections={of=p3 and p4}] (intersection-1) node[crossing] {};
\end{tikzpicture}
\end{document}
Which produces the following output:
As you might imagine, for more complex graphs this approach runs into readability issues; I would sometimes end up having to name almost all the paths in the drawing and name intersections
on dozens of pairs. The ideal case would be if I could just add something like showcrossings
to the tikzpicture
environment style and have it happen automatically.
I will post my own solution to this, but if anyone can improve on my approach or has a different approach I would be interested!