Unir caminhos de Tikz perfeitamente
Estou tentando usar o Tikz para desenhar nós de escalada .
Eu adaptei o código desta resposta https://tex.stackexchange.com/a/283009/229885para desenhar corda 3D usando caminhos Tikz (a ideia básica é sobrepor muitos caminhos de diferentes larguras e cores para obter uma aparência 3D). Funciona muito bem, mas há um problema que está me incomodando e não sei como resolver.
Na foto abaixo você pode ver dois nós. O rosa foi desenhado usando um único caminho e o branco foi desenhado usando dois caminhos. Preciso quebrar os caminhos para poder representar os cruzamentos de corda corretamente, mas quando faço isso posso ver uma "costura" onde os dois caminhos se encontram.

Aqui está o código que usei para criar esta imagem:
\documentclass[tikz, border=2mm]{standalone}
%%% The "Rope" command %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% \Rope[further options]{color}{width}{path definition} %
% %
\newcommand{\Rope}[4][] %
{ \pgfmathsetmacro{\RopeLevels}{25} %
\foreach \RopeLevel in {1,...,\RopeLevels} %
{ \pgfmathsetmacro{\RopeShade} %
{100 * (\RopeLevel-0.5) / \RopeLevels} %
\pgfmathsetlengthmacro{\RopeWidth} %
{sqrt(pow(#3, 2) - pow(#3 * (\RopeLevel-1) / \RopeLevels, 2))} %
\draw[#2!\RopeShade!black, line width=\RopeWidth, #1] #4; %
} %
} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}
\Rope[rounded corners]{pink} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\Rope[rounded corners]{white}{2mm}{ (1.5, 0.0) to (2.5, 1.0) to (2.0, 1.0) }
\Rope[rounded corners]{white}{2mm}{ (2.0, 1.0) to (1.5, 1.0) to (2.5, 0.0) }
\end{tikzpicture}
\end{document}
Tentei definir novos estilos de seta que estendem os caminhos além das coordenadas fornecidas, mas a costura ainda é visível de qualquer maneira.
Minhas perguntas são:
- Esta costura é real ou um artefato criado pelo meu leitor de PDF? (Estou usando Atril 1.24.0 no Xubuntu 20.04.1)
- Existe alguma maneira de unir caminhos Tikz perfeitamente?
- Mais em geral, existe uma maneira melhor de desenhar nós de escalada no LaTeX?
Agradeço antecipadamente,
Respostas
Aqui está uma versão que redesenha a parte do caminho perto do cruzamento para criar a aparência de passagem superior. Isso é, com efeito, o que o knots
pacote faz. Se você quiser desenhar caminhos mais complicados, talvez valha a pena examinar essa biblioteca, mas, neste caso, como sabemos onde fica a interseção, não precisamos dela.
\documentclass{article}
%\url{https://tex.stackexchange.com/q/572839/86}
\usepackage{tikz}
%%% The "Rope" command %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% \Rope[further options]{color}{width}{path definition} %
% %
\newcommand{\Rope}[4][] %
{ \pgfmathsetmacro{\RopeLevels}{25} %
\foreach \RopeLevel in {1,...,\RopeLevels} %
{ \pgfmathsetmacro{\RopeShade} %
{100 * (\RopeLevel-0.5) / \RopeLevels} %
\pgfmathsetlengthmacro{\RopeWidth} %
{sqrt(pow(#3, 2) - pow(#3 * (\RopeLevel-1) / \RopeLevels, 2))} %
\draw[#2!\RopeShade!black, line width=\RopeWidth, #1] #4; %
} %
} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}
\Rope[rounded corners]{pink} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\begin{scope}[xshift=1.5cm]
\Rope[rounded corners]{white} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\clip (0.5,0.5) circle[radius=3mm];
\Rope[rounded corners]{white} {2mm}{ (0.0, 0.0) to (1.0, 1.0) }
\end{scope}
\end{tikzpicture}
\end{document}
Isso produz a seguinte imagem.

Agora, isso tem artefatos no limite do clipe. Isso só é visível no visualizador e não apareceria quando impresso. Parece porque o caminho de recorte não é nítido e, portanto, quando uma linha é desenhada de forma múltipla, como em seu estilo de corda, partes dos níveis inferiores aparecem no limite.
Uma maneira de evitar isso é garantir que as camadas inferiores sejam recortadas com um círculo ligeiramente menor do que as camadas acima delas (adaptando a ideia em questão com "círculos na colheita" na biblioteca de nós tikz ). Como seus caminhos são desenhados dentro de um loop, precisamos fornecer um gancho para adicionar o caminho de recorte dentro quando for necessário. Para fazer isso, adicionei um escopo com um estilo opcional dentro do seu comando. Ao passar um clipe adequado para ele, os artefatos podem ser removidos.
\documentclass{article}
%\url{https://tex.stackexchange.com/q/572839/86}
\usepackage{tikz}
%%% The "Rope" command %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% \Rope[further options]{color}{width}{path definition} %
% %
\newcommand{\Rope}[4][] %
{ \pgfmathsetmacro{\RopeLevels}{25} %
\foreach \RopeLevel in {1,...,\RopeLevels} %
{ \pgfmathsetmacro{\RopeShade} %
{100 * (\RopeLevel-0.5) / \RopeLevels} %
\pgfmathsetlengthmacro{\RopeWidth} %
{sqrt(pow(#3, 2) - pow(#3 * (\RopeLevel-1) / \RopeLevels, 2))} %
\begin{scope}[rope scope/.try]
\draw[#2!\RopeShade!black, line width=\RopeWidth, #1] #4; %
\end{scope}
} %
} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}
\Rope[rounded corners]{pink} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\begin{scope}[xshift=1.5cm]
\Rope[rounded corners]{white} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\tikzset{
rope scope/.code={
\clip (0.5,0.5) circle[radius={3mm + \RopeLevel/25 pt}];
}
}
\Rope[rounded corners]{white} {2mm}{ (0.0, 0.0) to (1.0, 1.0) }
\end{scope}
\end{tikzpicture}
\end{document}
Isso produz:

Você pode encurtar um caminho por um comprimento negativo e, assim, aumentá-lo para criar uma pequena sobreposição. Este truque cura coisas em muitos espectadores, mas talvez não em todos. Pelo menos não em todos os níveis de ampliação.
\documentclass[tikz, border=2mm]{standalone}
%%% The "Rope" command %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% \Rope[further options]{color}{width}{path definition} %
% %
\newcommand{\Rope}[4][] %
{ \pgfmathsetmacro{\RopeLevels}{25} %
\foreach \RopeLevel in {1,...,\RopeLevels} %
{ \pgfmathsetmacro{\RopeShade} %
{100 * (\RopeLevel-0.5) / \RopeLevels} %
\pgfmathsetlengthmacro{\RopeWidth} %
{sqrt(pow(#3, 2) - pow(#3 * (\RopeLevel-1) / \RopeLevels, 2))} %
\draw[#2!\RopeShade!black, line width=\RopeWidth, #1] #4; %
} %
} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}
\Rope[rounded corners]{pink} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\Rope[rounded corners]{white}{2mm}{ (1.5, 0.0) to (2.5, 1.0) to (2.0, 1.0) }
\Rope[rounded corners,shorten <=-0.2pt]{white}{2mm}{ (2.0, 1.0) to (1.5, 1.0) to (2.5, 0.0) }
\end{tikzpicture}
\end{document}

Este é o zoom máximo em Visualização em um Mac. O Acrobat Reader também é perfeito para a maioria das ampliações, mas não para todas.
Em princípio, é possível obter um resultado "perfeito" recortando parte do antigo caminho. Aqui está uma versão incrivelmente ajustada usando um dash pattern
.
\documentclass[tikz, border=2mm]{standalone}
%%% The "Rope" command %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% \Rope[further options]{color}{width}{path definition} %
% %
\newcommand{\Rope}[4][]{% %
\pgfmathsetmacro{\RopeLevels}{25} %
\foreach \RopeLevel in {1,...,\RopeLevels} %
{ \pgfmathtruncatemacro{\RopeShade} %
{100 * (\RopeLevel-0.5) / \RopeLevels} %
\pgfmathsetlengthmacro{\RopeWidth} %
{sqrt(pow(#3, 2) - pow(#3 * (\RopeLevel-1) / \RopeLevels, 2))} %
\draw[#2!\RopeShade!black, line width=\RopeWidth, #1] #4; %
} %
} %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}
\Rope[rounded corners]{pink} {2mm}{ (0.0, 0.0) to (1.0, 1.0) to (0.0, 1.0) to (1.0, 0.0) }
\Rope[rounded corners]{white}{2mm}{ (1.5, 0.0) to (2.5, 1.0) to (1.5, 1.0) to (2.5, 0.0) }
\Rope[rounded corners,dash pattern=on 79.02pt off 80pt]{white}{2mm}{ (1.5, 0.0) to (2.5, 1.0) to (1.5, 1.0) to (2.5, 0.0) }
\end{tikzpicture}
\end{document}
Este não parece ter nenhuma falha para ampliações arbitrárias ou visualizadores (eu apenas testei Preview
e Acrobat Reader
). Alguém poderia calcular o 79.02pt
? Sim, pelo menos neste caso. A maneira mais limpa de ir, porém, é usar este post .