50 绘制围道时,处理均匀地添加曲线上的箭头的最佳实践?

发布于 2026-11-09 22:09:38

如题,考虑如下的目标:

image.png

可以先看下面的这份代码:

\documentclass[tikz,border=3.14pt]{standalone}
\usetikzlibrary{bending,decorations.markings,arrows.meta,calc}
\begin{document}
\begin{tikzpicture}[>={Kite[inset=0pt,length=0.28cm,bend]},
    decoration={markings,
        mark= at position .15 with {\arrow{>}},
        mark= at position .46 with {\arrow{>}},
        mark= at position .65 with {\arrow{>}},
        mark= at position .82 with {\arrow{>}},
    }]
    \def\eps{0.3}
    \def\bbeta{17.25}    % β = 2·arcsin(ε/2)
    \def\bhalf{8.63}     % β/2
    \filldraw[postaction={decorate}, thick, fill=gray!40]
        (-1+\eps, 0)                          
        -- (1-\eps, 0)                       
        arc (180:90+\bhalf:\eps)             
        arc (\bbeta:90-\bbeta:1)              
        arc (-\bhalf:-180+\bhalf:\eps)       
        arc (90+\bbeta:180-\bbeta:1)    
        arc (90-\bhalf:0:\eps)            
        -- cycle;

    \draw[-Stealth] (-1.4, 0) -- (1.4, 0) node[below]{$\Re$};
    \draw[-Stealth] (0, -0.4) -- (0, 1.4) node[right]{$\Im$};
    \node[below left] at (0,0) {$O$};
    \fill ( 1, 0) circle (0.8pt);
    \fill (-1, 0) circle (0.8pt);
    \fill ( 0, 1) circle (0.8pt);
    \node[below] at ( 1, 0) {$(1,0)$};
    \node[below] at (-1, 0) {$(-1,0)$};
    \node[above] at ( 0, 1) {$(0,1)$};
\end{tikzpicture}

\end{document}

我大概有如下三个问题:

  • 这里曲线上(尤其是曲率较大时)的箭头不是预期的
  • 如何选择合适的多个比例来控制各个子路径“均匀”地分布在路径上
  • 如果需要「既精确又灵活地控制放置四个箭头的位置」,此处的四个比例:
    decoration={markings,
        mark= at position .15 with {\arrow{>}},
        mark= at position .46 with {\arrow{>}},
        mark= at position .65 with {\arrow{>}},
        mark= at position .82 with {\arrow{>}},
    }]

可能需要经过数十次的反复编译以及调整! 这很不方便,希望在这里探求「最佳实践」;-)

查看更多

关注者
1
被浏览
22
1 个回答
Sagittarius Rover
Sagittarius Rover 1小时前
这家伙很懒,什么也没写!

一个月前我在群里给出的方案是:

  • 把全路径划分为多个子路径,预先保存中间顶点
  • “均匀”的添加箭头,只要保证子路径使用middle arrow=0.5的默认值即可
  • 利用bengding,ext.arrows,ext.arrows-plus库提供的\arrow**{ext_Centered Stealth[bend]}}来准确的控制箭头的位置和正确的弯曲
\documentclass[tikz,border=3pt]{standalone}
\usepackage{lete-sans-math}
\usetikzlibrary{bending,arrows.meta,decorations.markings,ext.arrows,ext.arrows-plus}
\tikzset{
    middle arrow/.style={
        semithick,postaction={decorate},
        decoration={markings,mark=at position #1 with {\arrow**{ext_Centered Stealth[bend]}}}
    },middle arrow/.default={0.5}
}
\begin{document}
\begin{tikzpicture}[>=Stealth]
    \def\ang{17.5}\def\R{2.5}
    \pgfmathsetmacro{\r}{2*\R*sin(\ang/2)}
    \draw[thick,fill=gray!30]
        ({\R-\r},0) coordinate (A)
        arc (180:{90+\ang/2}:\r) coordinate (B)
        arc (\ang:{90-\ang}:\R) coordinate (C) 
        arc ({-\ang/2}:{-180+\ang/2}:\r) coordinate (D) 
        arc ({90+\ang}:{180-\ang}:\R) coordinate (E) 
        arc ({90-\ang/2}:0:\r) coordinate (F) 
        -- cycle;
    \path[middle arrow=0.4] (F) -- (A);
    \path[middle arrow] (A) arc (180:{90+\ang/2}:\r);
    \path[middle arrow] (B) arc (\ang:{90-\ang}:\R);
    \path[middle arrow=0.6] (C) arc ({-\ang/2}:{-180+\ang/2}:\r);
    \path[middle arrow] (D) arc ({90+\ang}:{180-\ang}:\R);
    \path[middle arrow] (E) arc ({90-\ang/2}:0:\r);
    \fill[radius=2pt] 
        (-\R,0) circle[] node[below] {$(-1,0)$}
        (+\R,0) circle[] node[below] {$(1,0)$}
        (0,+\R) circle[] node[above] {$(0,1)$}
        ;
    \draw[->] (-3,0) -- (3,0) node[right] {$\Re$};
    \draw[->] (0,-.5) node[above left] {$O$} -- (0,3.5) node[above] {$\Im$};
\end{tikzpicture}
\end{document}

不过这样其实似乎涉嫌重复绘制各段路径...

    \path[middle arrow] (A) arc (180:{90+\ang/2}:\r);
    \path[middle arrow] (B) arc (\ang:{90-\ang}:\R);
    \path[middle arrow=0.6] (C) arc ({-\ang/2}:{-180+\ang/2}:\r);
    \path[middle arrow] (D) arc ({90+\ang}:{180-\ang}:\R);
    \path[middle arrow] (E) arc ({90-\ang/2}:0:\r);

image.png

放大看看细节:

image.png

不知道是否有更好的方案...

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览