Décoration pour lignes / courbes auto-croisées

Nov 29 2020

Est-il possible de définir une décoration / postaction, pour tracer une double ligne de sorte qu'une ligne auto-sécante se dessine sur elle-même? Pour montrer ce que je veux dire, voyez ces spirales:

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

La spirale supérieure montre l'effet d'une double ligne normale et la spirale inférieure montre le résultat souhaité. Je souhaite que le résultat soit fait avec une seule \drawcommande pour éviter le rendu des artefacts et faire fonctionner l' smoothoption sur toute la spirale.

En fin de compte, je veux pouvoir utiliser le blanc comme couleur extérieure et créer ainsi un effet de croisement. Pour pouvoir mieux répondre aux questions sur ce site par exemple Spirales coniques et cylindriques

Je pensais que cela devrait être possible en faisant le double sur de petits segments du chemin au fur et à mesure qu'il est dessiné. Une approche naïve comme celle-ci:

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

ne fonctionne pas car la préaction est appliquée à l'ensemble du chemin et non aux segments.

Une solution encore meilleure serait si le chemin pouvait cliplui-même, de sorte que la traversée soit belle sur un fond non blanc. - Probablement assez compliqué.

Réponses

3 Noname Nov 28 2020 at 23:47

Voici un moyen avec le 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}

Veuillez noter qu'il existe déjà des styles complets pour cela dans cette réponse .

4 AndrewStacey Nov 30 2020 at 00:55

La knotsbibliothèque TikZ gère ce genre de choses. Il y a un léger problème avec l'utilisation de la plotcommande de dessin car cela crée beaucoup de lignes très courtes et ce n'est pas génial pour la façon dont cela knotsfonctionne car il recherche les intersections entre les sous-chemins. Heureusement, en utilisant la hobbybibliothèque, je peux réduire considérablement le nombre d'échantillons car elle interpole en utilisant des courbes de Bézier.

La knotsbibliothèque fonctionne en redessinant juste une partie de la courbe aux intersections pour produire l'effet de viaduc.

L'utilisation de l'option double avec la knotsbibliothèque peut produire des artefacts lorsque le PDF est affiché (mais pas lors de son impression). La méthode pour les supprimer est détaillée au problème avec les "crop circles" dans la bibliothèque de nœuds tikz

Voici le code:

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

Résultat: