Combinando pontas de seta no TikZ com pontas de seta no modo matemático

Combinando pontas de seta no TikZ com pontas de seta no modo matemático

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 arrowspermite 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 \toou \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:

insira a descrição da imagem aqui

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}

insira a descrição da imagem aqui

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.

Diagrama comutativo

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 toestilo de seta que é uma versão ajustada do -bad toestilo de seta na pergunta vinculada acima. Isso é o mais próximo que posso chegar do que você forneceu.

insira a descrição da imagem aqui

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 tikzversão o mais próximo possível da do amsmath.

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.

Um exemplo de ponta de flecha

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 \intoe 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
    }

informação relacionada