คลื่นเดี่ยวในเส้น tikzcd

Jan 10 2021

ฉันกำลังพยายามสร้างรูปแบบสำหรับลูกศรใน tikzcd ซึ่งเป็นทิลเดอร์ที่ยืดได้อย่างมีประสิทธิภาพ:

ฉันได้วาดตัวอย่างนี้โดยใช้ตัวเลือกที่ 1 ในคำตอบนี้แต่ฉันต้องคำนวณความยาวส่วนที่ถูกต้องสำหรับงูด้วยตนเอง

มีวิธีคำนวณโดยอัตโนมัติหรือไม่? ตัวอย่างเช่น:

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

ถ้าไม่มีวิธีอื่นหรือไม่?

ความช่วยเหลือใด ๆ จะได้รับการชื่นชมมาก

คำตอบ

2 Dave Jan 11 2021 at 04:03

ฉันมีวิธีแก้ปัญหาบางส่วนตามคำตอบนี้

ฉันได้คัดลอกมาโครตัวช่วยของพวกเขาอย่างครบถ้วนพร้อมกับครึ่งแรกของคำจำกัดความสไตล์ของพวกเขา รหัสเดียวที่ฉันรับผิดชอบคือรหัสที่อยู่ด้านล่างความคิดเห็น "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
\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

เมื่อใช้มาโครตัวช่วยฉันจะดึงจุดที่จะรวมและคำนวณระยะห่างระหว่างพวกเขา จากนั้นฉันใช้สิ่งนี้เพื่อกำหนดความกว้างและความยาวส่วนของงู

ค่าคงที่ที่ฉันใช้ในคำจำกัดความเหล่านี้ปรากฏขึ้นโดยพลการฉันพบว่าผ่านการทดลองและการปรับปรุง แต่ฉันจะดำเนินการตามแนวทางที่เข้มงวดยิ่งขึ้น


แล้ว

\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}

ให้


ปัญหาหลักของฉันในตอนนี้คือป้ายกำกับเหนือลูกศรใช้ไม่ได้อีกต่อไป ฉันจะพยายามแก้ไขและอัปเดตคำตอบนี้หากทำได้

หากใครมีวิธีที่ง่ายกว่านี้เพื่อหลีกเลี่ยงปัญหาดังกล่าวโปรดแจ้งให้เราทราบ!