![使用数学模式箭头匹配 TikZ 中的箭头](https://linux22.com/image/243403/%E4%BD%BF%E7%94%A8%E6%95%B0%E5%AD%A6%E6%A8%A1%E5%BC%8F%E7%AE%AD%E5%A4%B4%E5%8C%B9%E9%85%8D%20TikZ%20%E4%B8%AD%E7%9A%84%E7%AE%AD%E5%A4%B4.png)
TikZ 擅长绘制图表,但有一个功能让我很恼火,那就是 TikZ 提供的默认箭头不一定尊重您使用的任何字体的数学模式。我知道 TikZ 库arrows
允许您在几种不同类型的箭头之间进行选择,但没有一种箭头能提供与数学模式下绘制的箭头相同的箭头。
在 TikZ 中绘制图表时,我希望箭头与通过\to
或等命令绘制的箭头相匹配\xrightarrow{foo}
。
有谁知道如何解决这一问题?
正如安德鲁·斯泰西 (Andrew Stacey) 在下面的评论中所建议的那样,我确实应该为您提供一个我所谈论的例子。
使用以下代码:
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
我已经准备了一套完整的箭头尖匹配计算机现代箭头,和发布在 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
这是我正在使用的代码;它相当好地再现了计算机现代箭头。特别是,尖端比使用手册第 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
}