J'essaie de reproduire la figure ci-dessous à l'aide de pgfplots :

Twisted plot

J'ai vu une explication sur mathematica stackexchange. Elle va me servir d'exemple : je vais procéder de même. Ainsi vais-je tout d'abord dessiner une coupe de la figure, puis visser celle-ci en suivant le périmètre d'un cercle.

La vue en coupe est obtenue grâce au code suivant :

Ouvrir dans l'éditeur Overleaf
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{polar}
\begin{document}
\begin{tikzpicture}
  \begin{polaraxis}
    \addplot[mark=none, domain=0:360, samples=100]
      {sin(3*x) + 1.25}; 
  \end{polaraxis}
\end{tikzpicture}
\end{document}

2d plot

Puis je donne de celle-ci une vue en trois dimensions. Je colore ma figure pour plus de lisibilité. Par souci de simplification, je place la figure au niveau 0. Il est toujours possible de modifier cela ou de changer le point de vue.

Ouvrir dans l'éditeur Overleaf
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot3 [domain=0:360, samples=60, fill=blue!30, opacity=0.8]
      ( {cos(x)*(sin(3*x) + 1.25)},
        {sin(x)*(sin(3*x) + 1.25)}, 0 );
  \end{axis}
\end{tikzpicture}
\end{document}

3d plot

Il ne nous reste plus qu'à faire tourner la figure par rapport à son centre, pendant que celui-ci décrit un cercle selon un axe perpendiculaire au plan dans lequel s'inscrit la figure. On trouvera sur TeX stackexchange un premier exemple de rotation sur l'axe Z, obtenu grâce à la fonction ({sin(x)*y},{cos(x)*y},{ <function of y> }).

Outre le fil consacré à mathematica cité plus haut, on peut s'inspirer de la documentation dudit logiciel.

Car la question demeure : comment réaliser cette figure avec pgfplots ?

PS : cette question est la traduction de celle-ci, posée sur le forum germanophone texwelt.de.

Posée 04 Jul '17, 18:27

stefan's gravatar image

stefan ♦♦
8618
Taux d'acceptation : 50%

Modifiée 05 Jul '17, 12:54

Pathe's gravatar image

Pathe ♦♦
7.4k28196245

Cette question ne nécessite pas de support urgent : une solution (à but d'archive) va suivre mais sentez-vous libre de contribuer si vous le souhaitez.

(04 Jul '17, 18:28) stefan ♦♦ stefan's gravatar image

Il s'agit de réaliser une sorte de tore ouvert vissé, en fait. On peut s'inspirer de ce fil sur TeX stackexchange, intitulé Comment dessiner un tore ?

On y lira qu'un tore peut par exemple être obtenu par l'équation :

Ouvrir dans l'éditeur Overleaf
x(t,s) = (2+cos(t))*cos(s+pi/2) 
y(t,s) = (2+cos(t))*sin(s+pi/2) 
z(t,s) = sin(t)

dont z et t appartiennent à l'intervalle [0,2\pi].

Ouvrir dans l'éditeur Overleaf
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\pgfplotsset{trig format plots=rad}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot3[surf,
        colormap/cool,
        samples=20,
        domain=0:2*pi,y domain=0:2*pi,
        z buffer=sort]
      ({(2+cos(x))*cos(y+pi/2)}, 
      {(2+cos(x))*sin(y+pi/2)}, 
      {sin(x)});
  \end{axis}
\end{tikzpicture}
\end{document}

Il s'agit de dessiner en 3D la figure 2D obtenue par les équations suivantes :

Ouvrir dans l'éditeur Overleaf
x(t) = sin(3t)cos(t)
y(t) = sin(3t)sin(t)

Un peu de gamberge nous amène à :

Ouvrir dans l'éditeur Overleaf
x(t,s) = (4+(sin(3*(t))+1.25)*cos(t))*cos(s)
y(t,s) = (4+(sin(3*(t))+1.25)*cos(t))*sin(s)
z(t,s) = ((sin(3*(t))+1.25)*sin(t))

Ce qui nous donne, pour une valeur définie de s et t\in[0,2\pi] (160), le code et la figure suivants :

figure avec valeur définie

Ouvrir dans l'éditeur Overleaf
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[axis equal]
    \addplot3[
        surf,
        samples=50, samples y=30,
        colormap/cool,
        domain=0:360, y domain=0:180,
        z buffer=sort,
      ]
      ({4+(sin(3*(x))+1.25)*cos(x))*cos(160},
       {4+(sin(3*(x))+1.25)*cos(x))*sin(160},
       {(sin(3*(x))+1.25)*sin(x)});
  \end{axis}
\end{tikzpicture}
\end{document}

À partir de là, on peut faire varier s, par exemple si l'on a s\in[0,\pi], on obtient les code et figure suivants :

figure

Ouvrir dans l'éditeur Overleaf
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[axis equal]
    \addplot3[
        surf,
        samples=50, samples y=30,
        colormap/cool,
        domain=0:360, y domain=0:180,
        z buffer=sort,
      ]
      ({4+(sin(3*(x))+1.25)*cos(x))*cos(y},
       {4+(sin(3*(x))+1.25)*cos(x))*sin(y},
       {(sin(3*(x))+1.25)*sin(x)});
  \end{axis}
\end{tikzpicture}
\end{document}

Avec y domain=0:360:

complètement

Fort bien, mais de vissage, point. On ajoute un multiple de y : x+3*y.

On obtient le code suivant :

Ouvrir dans l'éditeur Overleaf
% Avec LuaLaTeX en raison du calcul difficile
\RequirePackage{luatex85}% solution temporaire pour standalone avec LuaTeX
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[axis equal]
    \addplot3[
      surf,
      domain    = 0:360,
      y domain  = 0:360,
      samples   = 100,
      samples y = 70,
      z buffer  = sort,
      colormap/cool,
    ]
    ( {(6+(sin(3*(x+3*y))+1.25)*cos(x))*cos(y)},
      {(6+(sin(3*(x+3*y))+1.25)*cos(x))*sin(y)},
      {((sin(3*(x+3*y))+1.25)*sin(x))} );
    \end{axis}
\end{tikzpicture}
\end{document}

Figure finale

Supplément:

Figure

Ouvrir dans l'éditeur Overleaf
% Avec LuaLaTeX
\RequirePackage{luatex85}% solution temporaire pour standalone avec LuaTeX
\documentclass{standalone}
\usepackage{pgfplots}
\usetikzlibrary{backgrounds}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[axis equal,
      hide axis,
      /tikz/background rectangle/.style = {
        left color    = black,
        right color   = black!20,
        shading angle = 135,
      },
      show background rectangle
    ]
    \addplot3[
      surf,
      shader      = flat,
      miter limit = 1,
      domain      = 0:360,
      y domain    = 0:360,
      samples     = 100,
      samples y   = 70,
      z buffer    = sort,
      colormap/hot2,
    ]
    ( {(6+(sin(3*(x+3*y))+1.25)*cos(x))*cos(y)},
      {(6+(sin(3*(x+3*y))+1.25)*cos(x))*sin(y)},
      {((sin(3*(x+3*y))+1.25)*sin(x))} );
  \end{axis}
\end{tikzpicture}
\end{document}

PS : cette réponse est une adaptation de celle citée plus haut ainsi que de celle-ci avec l'aide de cmhughes.

Lien permanent

Publiée 04 Jul '17, 19:13

stefan's gravatar image

stefan ♦♦
8618
Taux d'acceptation : 50%

Modifiée 05 Jul '17, 01:06

Pathe's gravatar image

Pathe ♦♦
7.4k28196245

L'auteur a également publié un billet de blog (en anglais) consacré au présent fil de discussions.

(05 Jul '17, 12:57) Pathe ♦♦ Pathe's gravatar image
Votre réponse
(dés)activer l'aperçu

Suivre cette question

Par courriel :

Une fois que vous serez enregistré, vous pourrez souscrire à n'importe quelle mise à jour ici

Par flux RSS :

Réponses

Réponses et commentaires

Bases de Markdown

  • *italique* ou _italique_
  • **gras** ou __gras__
  • Lien ::[texte](http://url.com/ "Titre ")
  • Image : ?![alt texte](/path/img.jpg "Titre ")
  • Liste numérotée : 1. Foo 2. Bar
  • Pour ajouter un passage à la ligne, ajoutez deux espaces à l'endroit où vous souhaitez que la ligne commence.
  • Les balises HTML de base sont également prises en charge.