I want to optimize the following code:
\documentclass{article}
%\pagestyle{empty}
% Figure dimensions
\newcommand{\defLength}[2]{\newlength{#1}\setlength{#1}{#2}}
\defLength{\figWidth}{0.99\columnwidth}
\defLength{\figHeight}{\textheight}
%\usepackage[textwidth=\figWidth,height=\figHeight,showframe]{geometry}
% Math
\usepackage[cmex10]{mathtools}
\interdisplaylinepenalty=2500
% Required
\usepackage{graphicx}
\usepackage{tikz}
%\usetikzlibrary{matrix}
%\usetikzlibrary{shapes.geometric}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
%\usetikzlibrary{decorations.pathreplacing} % for expanding waves
%\usetikzlibrary{decorations.markings}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{fit}
\usetikzlibrary{intersections}
\usetikzlibrary{backgrounds}
% https://tex.stackexchange.com/questions/54368/tikz-nodes-centering-with-small-font
\tikzset{every node/.append style={execute at begin node=\footnotesize}}
\tikzset{%
ball/.style = {draw, shape=circle, text width=0.15\figWidth, align=center, inner sep=2pt, outer sep=0pt},
caixa/.style = {draw, shape=rectangle, align=center, inner sep=0pt, outer sep=0pt},
seta/.style = {-{Stealth[round]}, shorten >=\setaShort},
%seta/.style = {->, >=stealth},
%seta/.style = {->,},
}
% Calculate the distance and angle between two nodes
% https://tex.stackexchange.com/questions/38473/how-can-i-compute-the-distance-between-two-coordinates-in-tikz
% https://tex.stackexchange.com/questions/39293/coordinates-a-b-compute-b-a-and-angle-between-x-and-b-a
\makeatletter
\newcommand{\getLengthAndAngle}[4]{%
\pgfmathanglebetweenpoints{\pgfpointanchor{#1}{#2}}
{\pgfpointanchor{#3}{#4}}
\global\let\myangle\pgfmathresult % we need a global macro
\pgfpointdiff{\pgfpointanchor{#1}{#2}}
{\pgfpointanchor{#3}{#4}}
\pgf@xa=\pgf@x % no need to use a new dimen
\pgf@ya=\pgf@y
%\pgfmathparse{veclen(\pgf@xa,\pgf@ya)/28.45274} % to convert from pt to cm
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)} % to convert from pt to cm
\global\let\mylength\pgfmathresult % we need a global macro
}
\makeatother
\defLength{\setaShort}{2pt}
\defLength{\fitWidth}{4pt}
\defLength{\reduceWidth}{1cm}
\def\nodeDist{0.05\figWidth}
% Draw arc
\def\centerarc[#1](#2)(#3:#4:#5)% [draw options] (center) (initial angle:final angle:radius)
{ \draw[#1] ($(#2)+({#5*cos(#3)},{#5*sin(#3)})$) arc (#3:#4:#5); }
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\begin{document}
\noindent%
\begin{tikzpicture}[node distance=\nodeDist, auto]
%\node [draw, shape=rectangle, text width=\figWidth, text height=0.2*\figHeight, inner sep=0pt, outer sep=0pt] (area) {};
\node [shape=rectangle, text width=\figWidth, text height=0.2*\figHeight, inner sep=0pt, outer sep=0pt] (area) {};
% Balls
\node [ball, anchor=west] at ($(area.west)+(\reduceWidth,0pt)+(\fitWidth,0)$) (ball0) {};
\node [draw, fit={(ball0)}, inner sep=\fitWidth] (fitball0) {};
\node [ball, anchor=east] at ($(area.east)+(-\reduceWidth,0pt)+(-\fitWidth,0)$) (ball1) {};
\node [draw, fit={(ball1)}, inner sep=\fitWidth] (fitball1) {};
\node [ball, below = 2*\nodeDist of ball0] (ball2) {};
\node [ball, below = of ball2] (ball3) {};
\node [draw, fit={(ball2)(ball3)}, inner sep=\fitWidth] (fitball2) {};
\node [ball, below = 2*\nodeDist of ball1] (ball4) {};
\node [ball, below = of ball4] (ball5) {};
\node [draw, fit={(ball4)(ball5)}, inner sep=\fitWidth] (fitball3) {};
\draw node[%
ball,
text width=0.05\figWidth,
append after command={(\tikzlastnode.135) -- (\tikzlastnode.315) (\tikzlastnode.45) -- (\tikzlastnode.225)},
inner sep=0pt] at ($(ball2)!0.4!(ball4)$) (multi0) {};
\draw node[%
ball,
text width=0.05\figWidth,
append after command={(\tikzlastnode.135) -- (\tikzlastnode.315) (\tikzlastnode.45) -- (\tikzlastnode.225)},
inner sep=0pt] at ($(ball3)!0.6!(ball5)$) (multi1) {};
\coordinate (auxa) at (multi0.east -| multi1.east);
\getLengthAndAngle{multi0}{west}{auxa}{center}
\coordinate (auxb) at ($(multi0.west)!0.5!(auxa)$);
\coordinate (auxc) at (auxb |- fitball3.south);
\draw node[%
caixa,
text width=\mylength pt,
text height=0.5*\mylength pt,
anchor=north,
append after command={([yshift=-6pt]\tikzlastnode.north) -- ++(-0.25*\mylength pt,0pt) -- ([yshift=-6pt]\tikzlastnode.north) -- ([yshift=6pt]\tikzlastnode.south) -- ++(0.25*\mylength pt,0pt)},
] at (auxc) (step) {};
\node [%
caixa,
text width=\mylength pt,
%text height=0.5*\mylength pt,
minimum height=0.5*\mylength pt,
below = of step,
] (impact) {};
% Connection between nodes
\draw [seta] (ball0) -- node [pos=0.13] (ball2multi0) {} (ball1);
\path [name path=ball2multi0path] (ball2) -- node [pos=0.7] (ball3multi1) {} (multi0) (multi0) edge[seta] (ball4); % will be repeated
\path [name path=ball3multi1path] (ball3) -- (multi1) (multi1) edge[seta] (ball5); % will be repeated
\coordinate (auxd) at (ball2multi0 -| ball3multi1);
\getLengthAndAngle{ball2multi0}{center}{auxd}{center}
\draw [seta, name path=ball2multi0impactpath] (ball2multi0) |- ([yshift=-0.5*\mylength pt]impact.west);
\draw [seta, name path=ball3multi1impactpath] (ball3multi1) |- ([yshift=0.5*\mylength pt]impact.west);
\draw [seta] (impact) -- (step);
\draw [seta, name path=stepmulti0path] (step.north -| multi0) -- (multi0);
\draw [seta] (step.north -| multi1) -- (multi1);
% Intersections
\path [name intersections={of=ball2multi0impactpath and ball2multi0path,by=inter1}];
\filldraw [white] (inter1) circle (2pt);
\path [name intersections={of=ball2multi0impactpath and ball3multi1path,by=inter2}];
\filldraw [white] (inter2) circle (2pt);
\path [name intersections={of=ball3multi1impactpath and ball3multi1path,by=inter3}];
\filldraw [white] (inter3) circle (2pt);
\path [name intersections={of=stepmulti0path and ball3multi1path,by=inter4}];
\filldraw [white] (inter4) circle (2pt);
\pgfmathparse{2pt+\pgflinewidth}\let\fix=\pgfmathresult
\centerarc[](inter1)(90:-90:\fix pt)) % -90 and 270 are different
\centerarc[](inter2)(90:-90:\fix pt)
\centerarc[](inter3)(90:-90:\fix pt)
\centerarc[](inter4)(90:-90:\fix pt)
\draw (ball2) -- (multi0); % repeated
\draw (ball3) -- (multi1); % repeated
\end{tikzpicture}
\end{document}
Namely, the drawing of the arc that shows the lines are not connected is clearly not good, since I have to use many workarounds (fill white, draw lines twice, etc.). I tried a solutions from here Intersection of 2 lines not really connected in TikZ, but it didn't work. I do believe that it is also possible to improve other parts of the code and put it more legible.
circuitikz
...?caixa
?standalone
? It can replacepreview
.