Decoração para linhas / curvas que se cruzam

Nov 29 2020

É possível definir uma decoração / postação, para traçar uma linha dupla de forma que uma linha que se autointercepte desenhe sobre si mesma? Para mostrar o que quero dizer, veja essas espirais:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[red, double=yellow, thick, domain=0:pi, smooth, samples=200] plot (\x, {cos(10*\x r)} , {sin(10*\x r)} );
\begin{scope}[yshift=-3cm]
\foreach \i in {1,...,10}
\draw[red, double=yellow, thick, domain=pi*(\i-1)/10:pi*\i/10, smooth, samples=200] plot (\x, {cos(10*\x r)} , {sin(10*\x r)} );
\end{scope}
\end{tikzpicture}
\end{document}

A espiral superior mostra o efeito de uma linha dupla normal e a espiral inferior mostra o resultado desejado. Desejo que o resultado seja feito com apenas um \drawcomando para evitar a renderização de artefatos e fazer a smoothopção funcionar em toda a espiral.

Em última análise, quero ser capaz de usar o branco como cor externa e, assim, criar um efeito de cruzamento. Para ser capaz de responder melhor às perguntas neste site, por exemplo, espirais cônicas e cilíndricas

Eu estava pensando que deveria ser possível fazendo o duplo em pequenos segmentos do caminho conforme ele está sendo desenhado. Uma abordagem ingênua como esta:

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary {decorations.pathmorphing}
\begin{document}
\begin{tikzpicture}
\draw[yellow, 
decorate, decoration={zigzag, segment length=1mm, amplitude=0mm},
preaction={draw, ultra thick, red},
domain=0:pi, samples=200] plot (\x, {cos(10*\x r)} , {sin(10*\x r)} );
\end{tikzpicture}
\end{document}

não funciona porque a pré-ação é aplicada a todo o caminho e não aos segmentos.

Uma solução ainda melhor seria se o clippróprio caminho pudesse , de forma que a travessia ficasse bonita em um fundo não branco. - Provavelmente muito complicado.

Respostas

3 Noname Nov 28 2020 at 23:47

Aqui está uma maneira com o show path construction.

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{tikzpicture}[path decomposition/.style={%
    postaction={decoration={show path construction,
    lineto code={
      \draw[#1]  (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
    },
    curveto code={
      \draw[#1]  (\tikzinputsegmentfirst) .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..(\tikzinputsegmentlast) ;
    },
    closepath code={
      \draw[#1]  (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) {closepath};} }
    ,decorate}}]
\draw[red, double=yellow, thick, domain=0:pi, smooth, samples=200,
path decomposition={red, double=yellow, thick}] plot (\x, {cos(10*\x r)} , {sin(10*\x r)} );
\begin{scope}[yshift=-3cm]
\foreach \i in {1,...,10}
\draw[red, double=yellow, thick, domain=pi*(\i-1)/10:pi*\i/10, smooth, samples=200] plot (\x, {cos(10*\x r)} , {sin(10*\x r)} );
\end{scope}
\end{tikzpicture}
\end{document}

Observe que já existem estilos completos para isso nesta resposta .

4 AndrewStacey Nov 30 2020 at 00:55

A knotsbiblioteca TikZ lida com esse tipo de coisa. Há um pequeno problema com o uso do plotcomando de desenho porque ele cria muitas linhas muito curtas e isso não é ótimo para a maneira que knotsfunciona, pois procura interseções entre subcaminhos. Felizmente, usando a hobbybiblioteca, posso reduzir o número de amostras consideravelmente, pois ela interpola usando curvas de Bezier.

A knotsbiblioteca funciona redesenhando apenas parte da curva nas interseções para produzir o efeito de viaduto.

Usar a opção dupla com a knotsbiblioteca pode produzir artefatos quando o PDF é visualizado (mas não quando é impresso). O método para removê-los é detalhado em problemas com "círculos nas plantações" na biblioteca de nós tikz

Aqui está o código:

\documentclass{article}
%\url{https://tex.stackexchange.com/q/572737/86}
\usepackage{tikz}
\usetikzlibrary{knots,hobby}

\tikzset{
  basic strand/.style={
    red,
    double=yellow,
    double distance=1pt,
  },
  crossing strand/.style={
    line width=1.8pt,
    only when rendering/.style={%
      draw=yellow,%
      line width=1pt,
      double=none,
    }
  }
}

\begin{document}
\begin{tikzpicture}[use Hobby shortcut]
\begin{knot}[
  consider self intersections=true,
  ignore endpoint intersections=false,
  background colour=red,
  every intersection/.style={
    crossing strand
  },
  only when rendering/.style={
    basic strand
  },
  clip width=1
]
\strand (0,1,0) \foreach \x in {1,...,80} { .. (\x/80*pi, {cos(22.5*\x )} , {sin(22.5*\x )} ) };
\end{knot}
\end{tikzpicture}
\end{document}

Resultado: