Сопоставление наконечников стрелок в TikZ с наконечниками стрелок в математическом режиме

Сопоставление наконечников стрелок в TikZ с наконечниками стрелок в математическом режиме

TikZ отлично рисует диаграммы, но есть одна особенность, которую я нахожу довольно раздражающей, а именно тот факт, что стрелка по умолчанию, предоставляемая TikZ, не обязательно учитывает математический режим в любом шрифте, который вы используете. Я знаю, что библиотека TikZ arrowsпозволяет вам выбирать между несколькими различными типами наконечников стрелок, но ни один из них не предлагает тот же наконечник, что и нарисованный в математическом режиме.

При рисовании диаграммы в TikZ я хочу, чтобы наконечники стрелок совпадали со стрелками, нарисованными с помощью таких команд, как \toили \xrightarrow{foo}.

Кто-нибудь знает, как это исправить?


Как предложил Эндрю Стейси в комментариях ниже, мне действительно следует привести пример того, о чем я говорю.

Используя следующий код:

An arrow tip produced by TikZ:  
\begin{tikzpicture}
\node (A) at (0,0){$A$};
\node (B) at (1,0){$B$.};

\path (A) edge[->] node[midway,above]{$f$} (B);
\end{tikzpicture}

An arrow tip produced by \texttt{amsmath}: $A \xrightarrow{f} B$.  

Я получаю следующий вывод:

введите описание изображения здесь

Я хочу, чтобы эти два наконечника стрел были идентичны.

решение1

Я подготовил полный набор наконечников стрел, соответствующих стрелкам Computer Modern, иразместил его на CTAN(а также некоторые обсуждения по этому вопросу и некоторые другие материалы, которые могут быть полезны для математических диаграмм).

Мои наконечники стрелок не такие точные, как у Кристиана, но они примерно такие же, как и те, которые можно получить, используя несколько штрихов (а не заполнение области), и на практике я нахожу результат вполне удовлетворительным.

Вот сравнение (сверху Computer Modern, снизу стрелка, нарисованная tikz).

\documentclass{article} 
\usepackage{tikz,tikz-cd,graphicx} 
\begin{document} 
\noindent\hspace{2mm} \scalebox{20}{$\hookrightarrow$} 
\vspace{2cm} 
\tikz \draw[line width=8pt,cm right hook-cm to] (0,0) to (7,0); 
\end{document}

введите описание изображения здесь

решение2

Вот еще один способ нарисовать наконечники стрел, похожие на Computer Modern, используя тонкий контур и заполняя его. Проблема с этим решением в том, что при печати в 10 точек наконечник становится почти невидимым. Поэтому, пожалуйста, не используйте этот код, пока кто-нибудь не найдет обходной путь. На экране результат, конечно, выглядит отлично; пример приведен ниже.

Коммутативная диаграмма

Вот код:

    \usepackage{tikz}
    \usetikzlibrary{matrix,arrows}
    \newlength{\myarrowsize} 
    \newlength{\myoldlinewidth}

    \pgfarrowsdeclare{myto}{myto}{
        \pgfsetdash{}{0pt} 
        \pgfsetbeveljoin 
        \pgfsetroundcap 
        \setlength{\myarrowsize}{0.6pt}
        \addtolength{\myarrowsize}{.5\pgflinewidth}
        \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
        \pgfarrowsrightextend{.7\pgflinewidth}
    }{
        \setlength{\myarrowsize}{0.6pt} 
        \addtolength{\myarrowsize}{.5\pgflinewidth}  
        \setlength{\myoldlinewidth}{\pgflinewidth}
        \pgfsetroundjoin
        % draw top half
        \pgfsetlinewidth{0.0001pt}
        \pgfpathmoveto{\pgfpoint{0.43\myarrowsize}{0}}
        \pgfpatharc{0}{70}{0.14\myarrowsize}
        \pgfpatharc{-110}{-169.5}{4\myarrowsize}
        \pgfpatharc{10.5}{189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{-170}{-119.5}{4.48\myarrowsize}
        % draw bottom half
        \pgfpathmoveto{\pgfpoint{0.43\myarrowsize}{0}}
        \pgfpatharc{0}{-70}{0.14\myarrowsize}
        \pgfpatharc{110}{169.5}{4\myarrowsize}
        \pgfpatharc{-10.5}{-189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{170}{119.5}{4.48\myarrowsize}
        \pgfpathclose
        \pgfsetstrokeopacity{0.25}
        \pgfusepathqfillstroke
    }

    \pgfarrowsdeclare{myonto}{myonto}{
        \pgfsetdash{}{0pt} 
        \pgfsetbeveljoin 
        \pgfsetroundcap 
        \setlength{\myarrowsize}{0.6pt}
        \addtolength{\myarrowsize}{.5\pgflinewidth}
        \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
        \pgfarrowsrightextend{.7\pgflinewidth}
    }{
        \setlength{\myarrowsize}{0.6pt} 
        \addtolength{\myarrowsize}{.5\pgflinewidth}  
        \setlength{\myoldlinewidth}{\pgflinewidth}
        \pgfsetroundjoin
        % draw top half
        \pgfsetlinewidth{0.0001pt}
        \pgfpathmoveto{\pgfpoint{0.43\myarrowsize}{0}}
        \pgfpatharc{0}{70}{0.14\myarrowsize}
        \pgfpatharc{-110}{-169.5}{4\myarrowsize}
        \pgfpatharc{10.5}{189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{-170}{-119.5}{4.48\myarrowsize}
        \pgfpathlineto{\pgfpoint{0.43\myarrowsize-0.3em}{0}}
        \pgfpatharc{0}{70}{0.14\myarrowsize}
        \pgfpatharc{-110}{-169.5}{4\myarrowsize}
        \pgfpatharc{10.5}{189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{-170}{-119.5}{4.48\myarrowsize}
        % draw bottom half
        \pgfpathmoveto{\pgfpoint{0.43\myarrowsize}{0}}
        \pgfpatharc{0}{-70}{0.14\myarrowsize}
        \pgfpatharc{110}{169.5}{4\myarrowsize}
        \pgfpatharc{-10.5}{-189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{170}{119.5}{4.48\myarrowsize}
        \pgfpathlineto{\pgfpoint{0.43\myarrowsize-0.3em}{0}}
        \pgfpatharc{0}{-70}{0.14\myarrowsize}
        \pgfpatharc{110}{169.5}{4\myarrowsize}
        \pgfpatharc{-10.5}{-189}{0.25\myarrowsize and 0.12\myarrowsize}
        \pgfpatharc{170}{119.5}{4.48\myarrowsize}
        \pgfpathclose
        \pgfsetstrokeopacity{0.25}
        \pgfusepathqfillstroke
    }

    \pgfarrowsdeclare{myhook}{myhook}{
        \setlength{\myarrowsize}{0.6pt}
        \addtolength{\myarrowsize}{.5\pgflinewidth}
        \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
        \pgfarrowsrightextend{.7\pgflinewidth}
    }{
        \setlength{\myarrowsize}{0.6pt} 
        \addtolength{\myarrowsize}{.5\pgflinewidth}  
        \pgfsetdash{}{+0pt}
        \pgfsetroundcap
        \pgfpathmoveto{\pgfqpoint{0pt}{-4.667\pgflinewidth}}
        \pgfpathcurveto
            {\pgfqpoint{4\pgflinewidth}{-4.667\pgflinewidth}}
            {\pgfqpoint{4\pgflinewidth}{0pt}}
            {\pgfpointorigin}
        \pgfusepathqstroke
    }

решение3

Этот вопрос намета-стрелки советыуказывает на руководство, в котором говорится, что кончики стрелок обычно не должны масштабироваться пропорционально ширине поддерживающей линии. Здесь я определил -my toстиль стрелки, который является измененной версией -bad toстиля стрелки в приведенном выше вопросе. Это примерно настолько близко, насколько я могу соответствовать тому, что вы предоставили.

введите описание изображения здесь

Примечания:

  • Поскольку это адаптировано из версии, которая масштабируется с шириной линий, это не даст очень хороших результатов с другими ширинами линий (на самом деле, это просто ужасно). Я попытался получить ширину линии из версии, tikzмаксимально приближенную к той, что из amsmath.

Код:

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\pgfarrowsdeclare{my to}{my to}
{
  \pgfarrowsleftextend{-2\pgflinewidth}
  \pgfarrowsrightextend{\pgflinewidth}
}
{
  \pgfsetlinewidth{0.8\pgflinewidth}
  \pgfsetdash{}{0pt}
  \pgfsetroundcap
  \pgfsetroundjoin
  \pgfpathmoveto{\pgfpoint{-5.5\pgflinewidth}{7.5\pgflinewidth}}
  \pgfpathcurveto
  {\pgfpoint{-4.0\pgflinewidth}{0.1\pgflinewidth}}
  {\pgfpoint{0pt}{0.25\pgflinewidth}}
  {\pgfpoint{0.75\pgflinewidth}{0pt}}
  \pgfpathcurveto
  {\pgfpoint{0pt}{-0.25\pgflinewidth}}
  {\pgfpoint{-4.0\pgflinewidth}{-0.1\pgflinewidth}}
  {\pgfpoint{-5.5\pgflinewidth}{-7.5\pgflinewidth}}
  \pgfusepathqstroke
}


\begin{document}
\begin{tikzpicture}
    \node (A) at (0,0){$A$};
    \node (B) at (0.82,0){$B$};
    \path (A) edge[-my to,line width=0.42pt]  (B);
\end{tikzpicture}

\hspace{0.33em}$A \xrightarrow{} B$
\end{document}

решение4

Вот код, который я использую; он довольно хорошо воспроизводит наконечники стрел Computer Modern. В частности, наконечник тоньше и менее закруглен, чем тот, который получается методом Раздела 74 руководства. Идея заключается в том, чтобы использовать несколько дуг (нарисованных с половинной толщиной) для создания контура, а затем заполнить его.

Вот пример результата: черная стрелка — это Computer Modern (созданная с помощью \longrightarrow), красная стрелка — сгенерированная с помощью кода ниже.

Пример наконечника стрелы

Я не настолько эксперт, чтобы подогнать размер наконечника стрелки под размер шрифта и т. д. Вторая проблема заключается в том, что при низком уровне масштабирования или при печати линии кажутся немного слишком толстыми. Поскольку код не работает с , я также \pgfdeclarearrowsdoubleвключил код для \intoи стрелок.\onto

    \usepackage{tikz}
    \usetikzlibrary{matrix,arrows}
    \newlength{\myarrowsize} 

    % Version similar to Computer Modern
    \pgfarrowsdeclare{cmto}{cmto}{
            \pgfsetdash{}{0pt} 
            \pgfsetbeveljoin 
            \pgfsetroundcap 
            \setlength{\myarrowsize}{0.6pt}
            \addtolength{\myarrowsize}{.5\pgflinewidth}
            \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
            \pgfarrowsrightextend{.8\pgflinewidth}
    }{
            \setlength{\myarrowsize}{0.6pt} 
            \addtolength{\myarrowsize}{.5\pgflinewidth}  
            \pgfsetlinewidth{0.5\pgflinewidth}
            \pgfsetroundjoin
            % top half
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth}{0}}
            \pgfpatharc{-109}{-170}{4\myarrowsize}
            \pgfpatharc{10}{189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{-170}{-115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % bottom half
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth}{0}}
            \pgfpatharc{109}{170}{4\myarrowsize}
            \pgfpatharc{-10}{-189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{170}{115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % Change line width back
            \pgfsetlinewidth{2\pgflinewidth}
    }

    \pgfarrowsdeclare{cmonto}{cmonto}{
            \pgfsetdash{}{0pt} 
            \pgfsetbeveljoin 
            \pgfsetroundcap 
            \setlength{\myarrowsize}{0.6pt}
            \addtolength{\myarrowsize}{.5\pgflinewidth}
            \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
            \pgfarrowsrightextend{.8\pgflinewidth}
    }{
            \setlength{\myarrowsize}{0.6pt} 
            \addtolength{\myarrowsize}{.5\pgflinewidth}  
            \pgfsetlinewidth{0.5\pgflinewidth}
            \pgfsetroundjoin
            % top half
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth}{0}}
            \pgfpatharc{-109}{-170}{4\myarrowsize}
            \pgfpatharc{10}{189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{-170}{-115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % bottom half
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth}{0}}
            \pgfpatharc{109}{170}{4\myarrowsize}
            \pgfpatharc{-10}{-189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{170}{115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % top half (2)
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth-0.3em}{0}}
            \pgfpatharc{-109}{-170}{4\myarrowsize}
            \pgfpatharc{10}{189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{-170}{-115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % bottom half (2)
            \pgfpathmoveto{\pgfpoint{1.5\pgflinewidth-0.3em}{0}}
            \pgfpatharc{109}{170}{4\myarrowsize}
            \pgfpatharc{-10}{-189}{0.58\pgflinewidth and 0.2\pgflinewidth}
            \pgfpatharc{170}{115}{4\myarrowsize+\pgflinewidth}
            \pgfpathclose
            \pgfusepathqfillstroke
            % Change line width back
            \pgfsetlinewidth{2\pgflinewidth}
    }

    \pgfarrowsdeclare{cmhook}{cmhook}{
            \pgfsetdash{}{0pt} 
            \pgfsetbeveljoin 
            \pgfsetroundcap 
            \setlength{\myarrowsize}{0.6pt}
            \addtolength{\myarrowsize}{.5\pgflinewidth}
            \pgfarrowsleftextend{-4\myarrowsize-.5\pgflinewidth} 
            \pgfarrowsrightextend{.8\pgflinewidth}
    }{
            \setlength{\myarrowsize}{0.6pt} 
            \addtolength{\myarrowsize}{.5\pgflinewidth}  
            \pgfsetdash{}{0pt}
            \pgfsetroundcap
            \pgfpathmoveto{\pgfqpoint{0pt}{-4.667\pgflinewidth}}
            \pgfpathcurveto
            {\pgfqpoint{4\pgflinewidth}{-4.667\pgflinewidth}}
            {\pgfqpoint{4\pgflinewidth}{0pt}}
            {\pgfpointorigin}
            \pgfusepathqstroke
    }

Связанный контент