
O TikZ é ótimo para desenhar diagramas, mas há um recurso que considero bastante irritante: o fato de que a ponta de seta padrão fornecida pelo TikZ não respeita necessariamente o modo matemático em qualquer fonte que você esteja usando. Eu sei que a biblioteca TikZ arrows
permite escolher entre vários tipos diferentes de pontas de seta, mas nenhuma delas oferece a mesma ponta de seta desenhada no modo matemático.
Ao desenhar um diagrama no TikZ, quero que as pontas das setas correspondam às pontas das setas desenhadas por comandos como \to
ou \xrightarrow{foo}
.
Alguém sabe como consertar isso?
Conforme sugerido por Andrew Stacey nos comentários abaixo, eu realmente deveria fornecer um exemplo do que estou falando.
Usando o seguinte código:
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$.
Eu recebo a seguinte saída:
Quero que essas duas pontas de flecha sejam idênticas.
Responder1
Eu preparei um conjunto abrangente de pontas de seta que combinam com as setas do Computer Modern, epostei no CTAN(juntamente com alguma discussão sobre este assunto e mais algumas coisas que podem ser úteis para diagramas matemáticos).
As pontas das minhas flechas não são tão precisas quanto as de Christian, mas são tão boas quanto se pode obter usando alguns traços de linha (em vez de preencher uma região) e, na prática, acho o resultado bom o suficiente.
Aqui está uma comparação (Computer Modern acima, seta desenhada em tikz abaixo).
\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}
Responder2
Aqui está outra maneira de desenhar pontas de flecha que se parecem com as do Computador Moderno, usando um contorno fino e preenchendo-o. O problema dessa solução é que, quando impressa em 10 pontos, a ponta da flecha fica quase invisível. Portanto, não use este código antes que alguém encontre uma solução alternativa. Na tela, o resultado parece bom, é claro; um exemplo está incluído abaixo.
Aqui está o código:
\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
}
Responder3
Esta pergunta emdicas de meta setaaponta para o manual que diz que as pontas das setas normalmente não devem ser dimensionadas em proporção à largura da linha de suporte. Aqui eu defini um -my to
estilo de seta que é uma versão ajustada do -bad to
estilo de seta na pergunta vinculada acima. Isso é o mais próximo que posso chegar do que você forneceu.
Notas:
- Como isso é adaptado de uma versão que é dimensionada com larguras de linha, isso não produzirá resultados muito bons com outras larguras de linha (na verdade, é horrível). Tentei obter a largura da linha da
tikz
versão o mais próximo possível da doamsmath
.
Código:
\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}
Responder4
Aqui está o código que estou usando; ele reproduz bastante bem as pontas de seta do Computer Modern. Em particular, a ponta é mais fina e menos arredondada do que a obtida com o método da Seção 74 do manual. A ideia é usar vários arcos (desenhados com metade da espessura) para criar um contorno e depois preenchê-lo.
Aqui está um exemplo do resultado: a seta preta é a da Computer Modern (produzida com \longrightarrow
), a seta vermelha é produzida pelo código abaixo.
Não sou especialista o suficiente para ajustar o tamanho da ponta da seta ao tamanho da fonte, etc. Um segundo problema é que, em níveis baixos de zoom ou na impressão, as linhas parecem um pouco grossas demais. Como o código não funciona com \pgfdeclarearrowsdouble
, incluí também o código para \into
e setas.\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
}