Onda única en línea tikzcd
Estoy tratando de crear un formato para flechas en tikzcd que es efectivamente una tilde estirada:
Dibujé este ejemplo usando la Opción 1 en esta respuesta , pero tuve que calcular manualmente la longitud correcta del segmento para la serpiente.
¿Hay alguna forma de calcular esto automáticamente? Diga por ejemplo:
arrows={decorate, decoration={snake, segment length=DISTANCE/2, amplitude=0.5mm}}
Si no es así, ¿existe un enfoque alternativo?
Cualquier ayuda será muy apreciada.
Respuestas
Tengo una solución parcial basada en esta respuesta .
He copiado su macro auxiliar en su totalidad, junto con la mayor parte de la primera mitad de su definición de estilo. El único código del que soy responsable es el que está debajo del comentario "Dibujar la ola":
\makeatletter
% This helper macro finds the start and endpoints of a line between the source and target nodes and stores them in \sourcecoordinate and \targetcoordinate.
% #1 -- source node
% #2 -- target node
\def\findedgesourcetarget#1#2{
\let\sourcecoordinate\pgfutil@empty
\ifx\tikzcd@startanchor\pgfutil@empty % Check that the source doesn't have a specified anchor
\def\tempa{\pgfpointanchor{#1}{center}}% if so, start by taking the center of that coordinate
\else
\edef\tempa{\noexpand\pgfpointanchor{#1}{\expandafter\@gobble\tikzcd@startanchor}} % If it has an anchor, use that
\let\sourcecoordinate\tempa
\fi
\ifx\tikzcd@endanchor\pgfutil@empty % check that the target doesn't have a specified anchor
\def\tempb{\pgfpointshapeborder{#2}{\tempa}}% if so, our end point is the point on the boundary of node b that is in the direction of our initial start coordinate
\else
\edef\tempb{\noexpand\pgfpointanchor{#2}{\expandafter\@gobble\tikzcd@endanchor}}% If it has a specified anchor, use that
\fi
\let\targetcoordinate\tempb
\ifx\sourcecoordinate\pgfutil@empty%
\def\sourcecoordinate{\pgfpointshapeborder{#1}{\tempb}}%
\fi
}
\tikzset{wave/.style = {
-,
to path={\pgfextra{
\findedgesourcetarget{\tikzcd@ar@start}{\tikzcd@ar@target} % find endpoints
% Rotate coordinate system so that line goes in x direction
\ifx\tikzcd@startanchor\pgfutil@empty
\def\tikzcd@startanchor{.center}
\fi
\ifx\tikzcd@endanchor\pgfutil@empty
\def\tikzcd@endanchor{.center}
\fi
\pgfmathanglebetweenpoints{\pgfpointanchor{\tikzcd@ar@start}{\expandafter\@gobble\tikzcd@startanchor}}{\pgfpointanchor{\tikzcd@ar@target}{\expandafter\@gobble\tikzcd@endanchor}}
\pgftransformrotate{\pgfmathresult}
% Draw the wave
\newdimen\xdiff
\pgfextractx{\xdiff}{\pgfpointdiff{\sourcecoordinate}{\targetcoordinate}}
\newdimen\ydiff
\pgfextracty{\ydiff}{\pgfpointdiff{\sourcecoordinate}{\targetcoordinate}}
\newdimen\finalDist
\pgfmathparse{abs(veclen(\xdiff,\ydiff))*0.85}
\pgfmathsetlength\finalDist{\pgfmathresult pt}
\pgfmathsetlength\pgfdecorationsegmentlength{\finalDist}
\pgfmathparse{0.038*\finalDist+0.6}
\pgfmathsetlength\pgfdecorationsegmentamplitude{\pgfmathresult pt}
\pgfsetarrows{->}
\pgfpathmoveto{\sourcecoordinate}
\pgfpathsnaketo{snake}{\targetcoordinate}
\pgfusepath{stroke}
}}}}
\makeatother
Usando la macro auxiliar, recupero los puntos que se unirán y calculo la distancia entre ellos. Luego uso esto para definir la amplitud y la longitud del segmento de la serpiente.
Las constantes que utilizo en estas definiciones parecen arbitrarias, las encontré a través de pruebas y mejoras, pero trabajaré en un enfoque más riguroso.
Entonces
\begin{center}
Original method:
\begin{tikzcd}[arrows={decorate, decoration={snake,segment length=7.3mm, amplitude=0.5mm}}]
A \arrow[r,"",decorate=true] & B
\end{tikzcd}
\end{center}
\hspace{2cm}
\begin{center}
Custom style
\begin{tikzcd}
A \arrow[r, wave] & B & & \\
A \arrow[rr, wave] & & B & \\
A \arrow[rrr, wave] & & & B
\end{tikzcd}
\end{center}
da
Mi principal problema actualmente es que las etiquetas sobre las flechas ya no funcionan. Intentaré solucionar este problema y actualizaré esta respuesta si puedo.
Si alguien tiene un enfoque más simple que evita estos problemas, ¡hágamelo saber!