Płynne łączenie ścieżek Tikz

Nov 29 2020

Próbuję użyć Tikza do rysowania węzłów wspinaczkowych .

Dostosowałem kod z tej odpowiedzi https://tex.stackexchange.com/a/283009/229885narysować trójwymiarową linę za pomocą ścieżek Tikz (podstawowym pomysłem jest nałożenie wielu ścieżek o różnych szerokościach i kolorach, aby uzyskać efekt 3D). Działa świetnie, ale jest problem, który mnie niepokoi i nie wiem, jak go rozwiązać.

Na poniższym obrazku widać dwa węzły. Różowa została narysowana przy użyciu jednej ścieżki, a biała przy użyciu dwóch ścieżek. Muszę przerwać ścieżki, aby móc poprawnie przedstawić skrzyżowania lin, ale kiedy to robię, widzę „szew”, w którym spotykają się obie ścieżki.

Oto kod, którego użyłem do stworzenia tego obrazu:

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

Próbowałem zdefiniować nowe style strzałek, które wydłużają ścieżki poza podane współrzędne, ale szew jest nadal widoczny bez względu na wszystko.

Moje pytania to:

  • Czy ten szew jest prawdziwy, czy artefakt utworzony przez mój czytnik PDF? (Używam Atril 1.24.0 na Xubuntu 20.04.1)
  • Czy istnieje sposób na bezproblemowe dołączanie do ścieżek Tikz?
  • Mówiąc bardziej ogólnie, czy istnieje lepszy sposób rysowania węzłów wspinaczkowych w LaTeX?

Z góry dziękuję,

Odpowiedzi

6 AndrewStacey Nov 29 2020 at 20:05

Oto wersja, która przerysowuje część ścieżki w pobliżu skrzyżowania, aby stworzyć efekt przejazdu. Tak właśnie działa knotspakiet. Jeśli chcesz narysować bardziej skomplikowane ścieżki, warto zajrzeć do tej biblioteki, ale w tym przypadku, ponieważ wiemy, gdzie jest skrzyżowanie, nie potrzebujemy jej.

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

Daje to następujący obraz.

Teraz to ma artefakty na granicy klipu. Jest to widoczne tylko w przeglądarce i nie pojawi się po wydrukowaniu. Pojawia się, ponieważ ścieżka przycinająca nie jest ostra, a więc gdy linia jest wielokrotnie rysowana, jak w twoim stylu liny, wówczas części niższych poziomów prześwitują na granicy.

Jednym ze sposobów uniknięcia tego jest upewnienie się, że warstwy pod spodem są przycinane nieco mniejszym okręgiem niż warstwy na nich leżące (dostosowanie pomysłu do problemu z „kręgami zbożowymi” w bibliotece węzłów tikz ). Ponieważ ścieżki są rysowane wewnątrz pętli, musimy zapewnić haczyk, aby dodać ścieżkę przycinającą do środka, gdy jest to potrzebne. Aby to zrobić, dodałem zakres z opcjonalnym stylem wewnątrz twojego polecenia. Przekazując do tego odpowiedni klip, można usunąć artefakty.

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

To daje:

8 Noname Nov 29 2020 at 16:11

Możesz skrócić ścieżkę o ujemną długość, a tym samym wydłużyć ją, tworząc niewielkie nakładanie się. Ta sztuczka leczy sytuację u wielu widzów, ale może nie u wszystkich. Przynajmniej nie na wszystkich poziomach powiększenia.

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

To jest maksymalne powiększenie w obszarze Podgląd na komputerze Mac. Acrobat Reader działa również bezproblemowo dla większości powiększeń, ale nie dla wszystkich.

Zasadniczo możliwe jest uzyskanie „doskonałego” wyniku poprzez wycięcie części starej ścieżki. Oto niesamowicie dostrojona wersja z rozszerzeniem 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}

Ten nie wydaje się mieć żadnych usterek dla dowolnych powiększeń lub przeglądarek (testowałem tylko Previewi Acrobat Reader). Czy można obliczyć 79.02pt? Tak, przynajmniej w tym przypadku. Jednak prostszym sposobem jest skorzystanie z tego wpisu .