
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
}