TransWikia.com

Single Wave in tikzcd Line

TeX - LaTeX Asked on April 4, 2021

I’m trying to create a format for arrows in tikzcd which is effectively a stretched tilde:
arrow example

I have drawn this example using Option 1 in this answer, but I have had to manually calculate the correct segment length for the snake.

Is there a way to calculate this automatically? Say for example:

arrows={decorate, decoration={snake, segment length=DISTANCE/2, amplitude=0.5mm}}

If not, is there an alternative approach?

Any help would be much appreciated.

One Answer

I have a partial solution based on this answer.

I have copied their helper macro in its entirety, along with most of the first half of their style definition. The only code I am responsible for is that which is below the comment "Draw the wave":

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
deffindedgesourcetarget#1#2{
letsourcecoordinatepgfutil@empty
ifxtikzcd@startanchorpgfutil@empty % Check that the source doesn't have a specified anchor
    deftempa{pgfpointanchor{#1}{center}}% if so, start by taking the center of that coordinate
else
    edeftempa{noexpandpgfpointanchor{#1}{expandafter@gobbletikzcd@startanchor}} % If it has an anchor, use that
    letsourcecoordinatetempa
fi
ifxtikzcd@endanchorpgfutil@empty % check that the target doesn't have a specified anchor
    deftempb{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
    edeftempb{noexpandpgfpointanchor{#2}{expandafter@gobbletikzcd@endanchor}}% If it has a specified anchor, use that
fi
lettargetcoordinatetempb
ifxsourcecoordinatepgfutil@empty%
    defsourcecoordinate{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
    ifxtikzcd@startanchorpgfutil@empty
        deftikzcd@startanchor{.center}
    fi
    ifxtikzcd@endanchorpgfutil@empty
        deftikzcd@endanchor{.center}
    fi
    pgfmathanglebetweenpoints{pgfpointanchor{tikzcd@ar@start}{expandafter@gobbletikzcd@startanchor}}{pgfpointanchor{tikzcd@ar@target}{expandafter@gobbletikzcd@endanchor}}
    pgftransformrotate{pgfmathresult}
    % Draw the wave
    newdimenxdiff
    pgfextractx{xdiff}{pgfpointdiff{sourcecoordinate}{targetcoordinate}}
    newdimenydiff
    pgfextracty{ydiff}{pgfpointdiff{sourcecoordinate}{targetcoordinate}}
    newdimenfinalDist
    pgfmathparse{abs(veclen(xdiff,ydiff))*0.85}
    pgfmathsetlengthfinalDist{pgfmathresult pt}

    pgfmathsetlengthpgfdecorationsegmentlength{finalDist}

    pgfmathparse{0.038*finalDist+0.6}
    pgfmathsetlengthpgfdecorationsegmentamplitude{pgfmathresult pt}

    pgfsetarrows{->}

    pgfpathmoveto{sourcecoordinate}
    pgfpathsnaketo{snake}{targetcoordinate}

    pgfusepath{stroke}
}}}}

makeatother

Using the helper macro, I retrieve the points to be joined and calculate the distance between them. I then use this to define the amplitude and segment length of the snake.

The constants I use in these definitions appear arbitrary, I found them through trial and improvement, but I'll work on a more rigorous approach.


Then

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}

gives results comparison


My main issue currently is that labels above the arrows no longer work. I will try to fix this, and update this answer if I can.

If anybody has a simpler approach which avoids such problems then please let me know!

Answered by Dave on April 4, 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