Onda única na linha tikzcd
Estou tentando criar um formato para setas no tikzcd que é efetivamente um til esticado:
Desenhei este exemplo usando a Opção 1 nesta resposta , mas tive que calcular manualmente o comprimento correto do segmento para a cobra.
Existe uma maneira de calcular isso automaticamente? Diga por exemplo:
arrows={decorate, decoration={snake, segment length=DISTANCE/2, amplitude=0.5mm}}
Se não, existe uma abordagem alternativa?
Qualquer ajuda seria muito apreciada.
Respostas
Eu tenho uma solução parcial com base nesta resposta .
Copiei sua macro auxiliar em sua totalidade, junto com a maior parte da primeira metade de sua definição de estilo. O único código pelo qual sou responsável é o que está abaixo do comentário "Desenhe a onda":
\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 a macro auxiliar, recupero os pontos a serem unidos e calculo a distância entre eles. Eu então uso isso para definir a amplitude e o comprimento do segmento da cobra.
As constantes que uso nessas definições parecem arbitrárias, descobri-as por meio de tentativa e aprimoramento, mas vou trabalhar em uma abordagem mais rigorosa.
Então
\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}
dá
Meu principal problema atualmente é que os rótulos acima das setas não funcionam mais. Vou tentar consertar isso e atualizar esta resposta se puder.
Se alguém tiver uma abordagem mais simples que evite esses problemas, por favor, me avise!