Tikzパスにシームレスに参加する

Nov 29 2020

Tikzを使って登山の結び目を描いています。

私はこの答えからコードを適応させました https://tex.stackexchange.com/a/283009/229885Tikzパスを使用して3D風のロープを描画します(基本的な考え方は、さまざまな幅と色の多くのパスを重ね合わせて3Dの外観にすることです)。それはうまくいきますが、私を悩ませている問題があり、私は解決する方法がわかりません。

下の写真では、2つの結び目を見ることができます。ピンクのものは1つのパスを使用して描画され、白いものは2つのパスを使用して描画されています。ロープの交差点を正しく表現するには、パスを分割する必要がありますが、そうすると、両方のパスが交わる「継ぎ目」が表示されます。

この画像を作成するために使用したコードは次のとおりです。

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

指定された座標を超えてパスを拡張する新しい矢印スタイルを定義しようとしましたが、継ぎ目は何があっても表示されます。

私の質問は次のとおりです。

  • この継ぎ目は本物ですか、それともPDFリーダーによって作成されたアーティファクトですか?(Xubuntu20.04.1でAtril1.24.0を使用しています)
  • Tikzパスにシームレスに参加する方法はありますか?
  • より一般的には、LaTeXでクライミングノットを描くためのより良い方法はありますか?

前もって感謝します、

回答

6 AndrewStacey Nov 29 2020 at 20:05

これは、交差点の近くのパスの一部を再描画して、高架道路の外観を作成するバージョンです。これは、事実上、knotsパッケージが行うことです。より複雑なパスを描画したい場合は、そのライブラリを調べる価値があるかもしれませんが、この場合、交差点がどこにあるかがわかっているので、それは必要ありません。

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

これにより、次の画像が生成されます。

さて、これはクリップの境界にアーティファクトがあります。これはビューアにのみ表示され、印刷時には表示されません。これは、クリッピングパスがシャープではないために表示されます。そのため、ロープスタイルのように線を複数回描画すると、下位レベルの一部が境界で透けて見えます。

これを回避する1つの方法は、下のレイヤーが上のレイヤーよりもわずかに小さい円でクリップされるようにすることです(tikzノットライブラリの「ミステリーサークル」で問題となっているアイデアを採用します)。パスはループ内に描画されるため、必要に応じてクリッピングパスを内部に追加するためのフックを提供する必要があります。そのために、コマンド内にオプションのスタイルを持つスコープを追加しました。これに適切なクリップを渡すことにより、アーティファクトを取り除くことができます。

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

これにより、次のものが生成されます。

8 Noname Nov 29 2020 at 16:11

パスを負の長さだけ短くして、パスを長くして小さなオーバーラップを作成できます。このトリックは多くの視聴者の問題を解決しますが、すべてではないかもしれません。少なくともすべての倍率レベルではありません。

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

これは、Macのプレビューでの最大ズームです。Acrobat Readerは、ほとんどの倍率でシームレスですが、すべてではありません。

原則として、古いパスの一部を切り抜くことで「完璧な」結果を得ることができます。これは、を使用して信じられないほど調整されたバージョン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}

これは、任意の倍率またはビューアに対してグリッチがないようです(私はテストPreviewしただけAcrobat Readerです)。計算でき79.02ptますか?はい、少なくともこの場合は。ただし、よりクリーンな方法は、この投稿を使用することです。