使用“双线”和“结线”时绘制的半交叉

使用“双线”和“结线”时绘制的半交叉

我有一些类似于以下代码的内容(对于较长的示例表示歉意,但这对精确数字相当敏感):

\documentclass{article}
\usepackage{tikz}

\usetikzlibrary{
  knots,
  hobby,
}

\tikzset{
    knot diagram/every knot diagram/.append style={
        consider self intersections=true,
        ignore endpoint intersections=false,
        end tolerance=1pt,
        clip draw radius=12pt
    },
  knot diagram/only when rendering/.style={
        ultra thick,
        draw=blue!40!black,
        double=white,
        double distance=12pt
    }
}

\begin{document}
\begin{tikzpicture}
    \begin{knot}[
        draft mode=crossings,
        flip crossing/.list={2,4,6,7,10,12}
        ]
    \strand
        ([closed]0.5,0.5) to[out=-5,in=-135]
        (1.8,0.8) to[out=45,in=-135]
        (4.25,3.25) to[out=45,in=135]
        (5.75,3.25) to[out=-45,in=135]
        (8.2,0.8) to[out=-45,in=-175]
        (9.5,0.5) to[out=85,in=-45]
        %
        (9.2,1.8) to[out=135,in=-45]
        (7.75,3.25) to[out=135,in=45]
        (6.25,3.25) to[out=-135,in=45]
        (3.75,0.75) to[out=-135,in=-45]
        (2.25,0.75) to[out=135,in=-45]
        (0.8,2.2) to[out=135,in=-95]
        (0.5,3.5) to[out=5,in=135]
        %
        (1.8,3.2) to[out=-45,in=135]
        (4.25,0.75) to[out=-45,in=-135]
        (5.75,0.75) to[out=45,in=-135]
        (8.2,3.2) to[out=45,in=175]
        (9.5,3.5) to[out=-85,in=45]
        %
        (9.2,2.2) to[out=-135,in=45]
        (7.75,0.75) to[out=-135,in=-45]
        (6.25,0.75) to[out=135,in=-45]
        (3.75,3.25) to[out=135,in=45]
        (2.25,3.25) to[out=-135,in=45]
        (0.8,1.8) to[out=-135,in=95] cycle;
    \end{knot}
    \useasboundingbox (-0.5,-0.5) rectangle (10.5,4.5);
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot}[
        draft mode=crossings,
        flip crossing/.list={2,4,6,7,10,12}
        ]
    \strand
        ([closed]0.5,0.5) to[out=-5,in=-135]
        (1.9,0.9) to[out=45,in=-135]
        (4.25,3.25) to[out=45,in=135]
        (5.75,3.25) to[out=-45,in=135]
        (8.1,0.9) to[out=-45,in=-175]
        (9.5,0.5) to[out=85,in=-45]
        %
        (9.1,1.9) to[out=135,in=-45]
        (7.75,3.25) to[out=135,in=45]
        (6.25,3.25) to[out=-135,in=45]
        (3.75,0.75) to[out=-135,in=-45]
        (2.25,0.75) to[out=135,in=-45]
        (0.9,2.1) to[out=135,in=-95]
        (0.5,3.5) to[out=5,in=135]
        %
        (1.9,3.1) to[out=-45,in=135]
        (4.25,0.75) to[out=-45,in=-135]
        (5.75,0.75) to[out=45,in=-135]
        (8.1,3.1) to[out=45,in=175]
        (9.5,3.5) to[out=-85,in=45]
        %
        (9.1,2.1) to[out=-135,in=45]
        (7.75,0.75) to[out=-135,in=-45]
        (6.25,0.75) to[out=135,in=-45]
        (3.75,3.25) to[out=135,in=45]
        (2.25,3.25) to[out=-135,in=45]
        (0.9,1.9) to[out=-135,in=95] cycle;
    \end{knot}
    \useasboundingbox (-0.5,-0.5) rectangle (10.5,4.5);
\end{tikzpicture}
\end{document}

每个结点都以不同的方式显示问题,可能有不同的原因,以及一个偶然的问题(与第一个/最后一个点有关)。以下是输出:

使用 tikz knots 包来处理断结

请注意,我无法使用该celtic软件包,因为我不想要交替结 - 据我所知,使用该软件包无法实现这一点。(这些结看起来是非交替的,因为由于第一个/最后一个点的问题,交叉点变得不稳定)

主要问题是部分交叉。在第一个结中,我不知道为什么会发生这种情况;在第二个结中,控制点非常靠近另一个弧,我认为这是通过限制剪切圆而导致问题的,因为将这些控制点移开会使这个问题消失(按时间顺序,第一个结是为了解决这个问题而创建的)。但第一个结没有这样的问题;它只是出现了。

这似乎只是绘图方面的问题。只有double启用此功能时才会发生这种情况,但文档中并未实际记录此功能knots,因此我几乎没有其他方法可以继续处理。

需要注意的一个有趣的事情是剪辑圆的混叠伪影的平面的方向 - 特别是在第一幅图像中将其翻转以穿过 10(第二幅图像中为 9......我不确定为什么这些交叉数字会发生变化)

在我的实际文档中,第一个点和最后一个点产生交叉的问题并没有发生,所以我并不担心这个问题。

答案1

这里发生了几件事,其中一件事与如何最好地绘制这样的图片有关(我应该将其添加到文档中),其中一件事揭示了 knots 包中的一个小错误。

使用 knots 包绘制凯尔特风格的结时,double路径结果会出现一些问题。随着时间的推移,通过这里的几个问题,出现了一种绘制这些结的最佳方法,但这并不是显而易见的方法。

但更重要的是,由于您的控制点非常接近交叉点,并且您的路径非常宽,那么您就会遇到end tolerance使用方式的错误。此键用于告诉结库“靠近端点”是什么意思。这使用了两次,一次是为了抛出一个段“相交”下一个段的虚假交叉点。对于此测试,您需要将其设置end tolerance为非常小,因为您的控制点接近(真正的)交叉点(选项ignore endpoint intersections=false是导致左下角出现虚假交叉的原因;因为您的控制点都不是实际上在交叉点处,通过删除此选项并保持end tolerance较小值,您可以摆脱此交叉点而不影响图片的其余部分)。

end tolerance在另一个地方也使用。当算法检测到交叉点时,它会在交叉点附近再次绘制上部线。通常,它只绘制路径的相关段。但如果该段在交叉点附近结束,那么它还会绘制下一个(或上一个,视情况而定)段。算法end tolerance在这里再次使用。因此,end tolerance设置为非常小,这意味着应该绘制的段不是因为发现交叉点距离段的端点更远。我应该这里使用的是剪切半径。

我认为这就是你的半交叉所发生的情况。在检查自相交时,例行程序中还有一个步骤,即(可能)将贝塞尔曲线一分为二,以确保它们本身不会自相交。这(可能)发生在对角线路径上,然后由于路径end tolerance较小,因此只渲染了该路径的一部分。

这是您的代码:

\documentclass{article}
%\url{https://tex.stackexchange.com/q/580472/86}
\usepackage{tikz}

\usetikzlibrary{
  knots,
  hobby,
}

\tikzset{
  knot diagram/every knot diagram/.append style={
    consider self intersections=true,
    %        ignore endpoint intersections=false,
    end tolerance=1pt,
    clip width=1,
    background color=blue!40!black,
    only when rendering/.style={
      basic strand
    },
    every intersection/.style={
      crossing strand
    },
  },
  basic strand/.style={
    ultra thick,
    draw=blue!40!black,
    double=white,
    double distance=10pt
  },
  crossing strand/.style={
    line width=13.2pt,
    only when rendering/.style={%
      draw=white,%
      line width=10pt,
      double=none,
    }
  }
}

\begin{document}
\begin{tikzpicture}
    \begin{knot}[
%        draft mode=crossings,
        flip crossing/.list={4,6,7,10,12}
        ]
    \strand
        (0.5,0.5) to[out=-5,in=-135]
        (1.8,0.8) to[out=45,in=-135]
        (4.25,3.25) to[out=45,in=135]
        (5.75,3.25) to[out=-45,in=135]
        (8.2,0.8) to[out=-45,in=-175]
        (9.5,0.5) to[out=85,in=-45]
        %
        (9.2,1.8) to[out=135,in=-45]
        (7.75,3.25) to[out=135,in=45]
        (6.25,3.25) to[out=-135,in=45]
        (3.75,0.75) to[out=-135,in=-45]
        (2.25,0.75) to[out=135,in=-45]
        (0.8,2.2) to[out=135,in=-95]
        (0.5,3.5) to[out=5,in=135]
        %
        (1.8,3.2) to[out=-45,in=135]
        (4.25,0.75) to[out=-45,in=-135]
        (5.75,0.75) to[out=45,in=-135]
        (8.2,3.2) to[out=45,in=175]
        (9.5,3.5) to[out=-85,in=45]
        %
        (9.2,2.2) to[out=-135,in=45]
        (7.75,0.75) to[out=-135,in=-45]
        (6.25,0.75) to[out=135,in=-45]
        (3.75,3.25) to[out=135,in=45]
        (2.25,3.25) to[out=-135,in=45]
        (0.8,1.8) to[out=-135,in=95] cycle;
    \end{knot}
    \useasboundingbox (-0.5,-0.5) rectangle (10.5,4.5);
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot}[
%        draft mode=crossings,
        flip crossing/.list={2,4,6,7,10,12}
        ]
    \strand
        ([closed]0.5,0.5) to[out=-5,in=-135]
        (1.9,0.9) to[out=45,in=-135]
        (4.25,3.25) to[out=45,in=135]
        (5.75,3.25) to[out=-45,in=135]
        (8.1,0.9) to[out=-45,in=-175]
        (9.5,0.5) to[out=85,in=-45]
        %
        (9.1,1.9) to[out=135,in=-45]
        (7.75,3.25) to[out=135,in=45]
        (6.25,3.25) to[out=-135,in=45]
        (3.75,0.75) to[out=-135,in=-45]
        (2.25,0.75) to[out=135,in=-45]
        (0.9,2.1) to[out=135,in=-95]
        (0.5,3.5) to[out=5,in=135]
        %
        (1.9,3.1) to[out=-45,in=135]
        (4.25,0.75) to[out=-45,in=-135]
        (5.75,0.75) to[out=45,in=-135]
        (8.1,3.1) to[out=45,in=175]
        (9.5,3.5) to[out=-85,in=45]
        %
        (9.1,2.1) to[out=-135,in=45]
        (7.75,0.75) to[out=-135,in=-45]
        (6.25,0.75) to[out=135,in=-45]
        (3.75,3.25) to[out=135,in=45]
        (2.25,3.25) to[out=-135,in=45]
        (0.9,1.9) to[out=-135,in=95] cycle;
    \end{knot}
    \useasboundingbox (-0.5,-0.5) rectangle (10.5,4.5);
\end{tikzpicture}
\end{document}

凯尔特结

我刚刚将修复版本上传到github

(但我仍然可以看到其中上部的轻微伪影,这表明我可能还没有完全正确地修复 - 对于任何有数学倾向的人来说,这可能是因为我使用 l^1 范数来表示速度而不是 l^2 范数,所以我可能需要在某处使用 sqrt(2) 的因子。)

答案2

我为您提供另一种方法,直接使用 tikz。我的绘图是凯尔特式的,因为我真的不知道您想如何重叠线条。还有一个额外的示例供您了解如何任意重叠线条。

这是我的代码:

\begin{document}
\begin{tikzpicture}[line join=round, line cap=round, thick, blue, fill=blue!10]
  % Coordinates
  \pgfmathsetmacro\r{sqrt(2)}  
  \foreach\x in {1,...,5} \foreach\y in {1,2}
  {
    \coordinate (\x-\y-O) at (1.5*\r*\x,1.5*\r*\y);
    \coordinate (\x-\y-N) at ($(\x-\y-O)+(0,0.5*\r)$);
    \coordinate (\x-\y-S) at ($(\x-\y-O)-(0,0.5*\r)$);
    \coordinate (\x-\y-E) at ($(\x-\y-O)+(0.5*\r,0)$);
    \coordinate (\x-\y-W) at ($(\x-\y-O)-(0.5*\r,0)$);
  }
  % Middle section
  \foreach\x in {2,3,4}
  {
    \pgfmathtruncatemacro\xx{\x-1}
    \filldraw (\x-1-N) ++ (225:1) arc (225:315:1) --++ (45:1.5) --++
              (315:0.5) --++ (225:1.5) --++ (0,0) arc (315:225:1.5) --cycle;
    \filldraw (\x-2-W) --++ (315:2.5) --++ (225:0.5) --++ (135:2.5) -- cycle;
    \filldraw (\xx-2-S) --++ (45:1.5) --++ (0,0) arc (135:45:1.5) --++
              (225:0.5) --++ (0,0) arc (45:135:1) --++ (225:1.5) -- cycle;
  }
  % Corners
  \foreach \x/\y/\c/\a in {1/1/N/0, 1/2/E/270, 5/1/W/90, 5/2/S/180}
  {
    \begin{scope}[shift={(\x-\y-\c)},rotate=\a]
      \filldraw (0,0) --++ (135:0.5) --++ (0,0) arc (135:180:1.5) --++ (270:1.5-0.5*\r) --++
                (0:1.5-0.5*\r) --++ (0,0) arc (270:315:1.5) --++ (45:1.5) --++ (135:0.5) --++
                (225:1.5) --++ (0,0) arc (315:270:1) --++ (180:1-0.5*\r) --++ (90:1-0.5*\r) --++
                (0,0) arc (180:135:1) -- cycle;
    \end{scope}
  }
  % Non-celtic example (superposed, comment it if you want)
  \filldraw[draw=red,fill=red!10] (2-1-N) --++ (225:1.5) --++ (0,0) arc (315:270:1.5) --++
                (180:1.5-0.5*\r) --++ (90:1.5-0.5*\r) --++ (0,0) arc (180:135:1.5) --++ (45:2) --++
                (0,0) arc (135:45:1.5) --++ (315:3) --++ (225:0.5) --++ (135:3) --++
                (0,0) arc (45:135:1) --++ (225:2) --++ (0,0) arc (135:180:1) --++
                (270:1-0.5*\r) --++ (0:1-0.5*\r) --++ (0,0) arc (270:315:1) --++ (45:1.5) -- cycle;
% Auxiliar grid of squares
%  \foreach\x in {1,...,5} \foreach\y in {1,2}
%  {
%    \draw[thin,black,dashed] (\x-\y-E) -- (\x-\y-N) -- (\x-\y-W) -- (\x-\y-S) -- cycle;
%  }
\end{tikzpicture}
\end{document}

以及绘图: 在此处输入图片描述

答案3

我知道这个问题的最佳解决方案是 Andy 提出的解决方案,他使用了 knots 库,正如 OP 所希望的那样。

但我对之前的解决方案并不完全满意,它更适合凯尔特人的情况。所以,为了好玩,我只是画了另一个解决方案,更加参数化,轴也发生了变化,更适合非凯尔特人的情况。

新代码:

\documentclass[border=2mm]{standalone}
\usepackage    {tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[line join=round, line cap=round, thick, blue, rotate=-45]
  % Parameters
  \def\na{4}   % number of middle arcs
  \def\sp{1}   % separation between paths
  \def\wp{0.5} % width of the path
  % Distances
  \pgfmathsetmacro\sm {\sp+\wp}
  \pgfmathsetmacro\spd{sqrt(2)*\sp}
  \pgfmathsetmacro\wpd{sqrt(2)*\wp}
  \pgfmathsetmacro\smd{sqrt(2)*\sm}
  \pgfmathsetmacro\lc {0.5*(\spd-\sp)}
  % Central pattern (without crossings)
  \foreach\i in {1,...,\na}
  {
    \pgfmathsetmacro\x{\i*\sm}
    \coordinate (\i-O) at (\x,\x);                        % Square, center
    \coordinate (\i-N) at ($(\i-O)+(-0.5*\sm, 0.5*\sm)$); % Square, north 
    \coordinate (\i-S) at ($(\i-O)+( 0.5*\sm,-0.5*\sm)$); % ...
    \coordinate (\i-E) at ($(\i-O)+( 0.5*\sm, 0.5*\sm)$);
    \coordinate (\i-W) at ($(\i-O)+(-0.5*\sm,-0.5*\sm)$);
%    \node[red] at (\i-O) {\small\i-O};
%    \node[red] at (\i-N) {\small\i-N};
%    \node[red] at (\i-S) {\small\i-S};
%    \node[red] at (\i-E) {\small\i-E};
%    \node[red] at (\i-W) {\small\i-W};
    \draw ($(\i-O)-( 0.5*\sp, 0.5*\sp)$) rectangle ($(\i-O)+(0.5*\sp,0.5*\sp)$);
    \draw ($(\i-N)+(-0.5*\wp, 0.5*\wp)$) arc  (90:135:\sp+\wp);
    \draw ($(\i-N)+(-0.5*\wp, 0.5*\wp)$) arc (180:135:\sp+\wp);
    \draw ($(\i-S)+( 0.5*\wp,-0.5*\wp)$) arc (270:315:\sp+\wp);
    \draw ($(\i-S)+( 0.5*\wp,-0.5*\wp)$) arc   (0:-45:\sp+\wp);
    \draw ($(\i-E)+(-0.5*\wp, 0.5*\wp)$) --++ (-\sp,0) --++ (0,0) arc (180:135:\sp);
    \draw ($(\i-E)+( 0.5*\wp,-0.5*\wp)$) --++ (0,-\sp) --++ (0,0) arc (270:315:\sp);
    \draw ($(\i-W)+(-0.5*\wp, 0.5*\wp)$) --++  (0,\sp) --++ (0,0) arc  (90:135:\sp);
    \draw ($(\i-W)+( 0.5*\wp,-0.5*\wp)$) --++  (\sp,0) --++ (0,0) arc   (0:-45:\sp);
  }
  % Left corners
  \draw ($(1-W)+( 0.5*\wp,-0.5*\wp)$) arc (180:225:\sp) --++ (\lc,-\lc) --++ (\lc,\lc);
  \draw ($(1-W)+(-0.5*\wp, 0.5*\wp)$) arc (270:225:\sp) --++ (-\lc,\lc) --++ (\lc,\lc);
  \draw ($(1-W)+(-0.5*\wp,-0.5*\wp)$) arc (180:225:\sm) --++ ( 0.5*\wpd+\lc,-0.5*\wpd-\lc)
                                      --++ (0.5*\wpd+\lc,0.5*\wpd+\lc);
  \draw ($(1-W)+(-0.5*\wp,-0.5*\wp)$) arc (270:225:\sm) --++ (-0.5*\wpd-\lc, 0.5*\wpd+\lc)
                                      --++ (0.5*\wpd+\lc,0.5*\wpd+\lc);
  % Right corners
  \draw ($(\na-E)+(-0.5*\wp, 0.5*\wp)$) arc  (0:45:\sp) --++ (-\lc,\lc) --++ (-\lc,-\lc);
  \draw ($(\na-E)+( 0.5*\wp,-0.5*\wp)$) arc (90:45:\sp) --++ (\lc,-\lc) --++ (-\lc,-\lc);
  \draw ($(\na-E)+( 0.5*\wp, 0.5*\wp)$) arc  (0:45:\sm) --++ (-0.5*\wpd-\lc, 0.5*\wpd+\lc)
                                        --++ (-0.5*\wpd-\lc,-0.5*\wpd-\lc);
  \draw ($(\na-E)+( 0.5*\wp, 0.5*\wp)$) arc (90:45:\sm) --++ ( 0.5*\wpd+\lc,-0.5*\wpd-\lc)
                                        --++ (-0.5*\wpd-\lc,-0.5*\wpd-\lc);
  % NE Crossings
  \foreach \i/\C in {1/W, 1/S, 1/N, 2/S, 3/S, 3/N, 4/N, 4/S}
  {
    \draw ($(\i-\C)+(-0.5*\wp,-0.5*\wp)$) --++ (0,\wp);
    \draw ($(\i-\C)+( 0.5*\wp,-0.5*\wp)$) --++ (0,\wp);
  }
  % NW Crossings
  \foreach \i/\C in {2/W, 2/N, 3/W, 4/W, 4/E}
  {
    \draw ($(\i-\C)+(-0.5*\wp, 0.5*\wp)$) --++ (\wp,0);
    \draw ($(\i-\C)+(-0.5*\wp,-0.5*\wp)$) --++ (\wp,0);
  }
\end{tikzpicture}
\end{document}

还有(不太新的)图画: 在此处输入图片描述

相关内容