Pyramide de Sierpinski (dplotsetrotatedcoords)

Tout ce qui concerne le langage TeX/LaTeX et ses variantes. Ce langage est utilisable sur le forum via les balises tex.
[participation réservée aux utilisateurs inscrits]
Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
dhenin
Utilisateur débutant
Utilisateur débutant
Messages : 2
Inscription : dimanche 08 octobre 2023, 08:31
Statut actuel : Autre

[Résolu] Pyramide de Sierpinski (dplotsetrotatedcoords)

Message non lu par dhenin »

Bonjour,

Je voudrais réaliser une pyramide (tétraédrique, SABCD) de côté 2 cm dans un repère rouge d'origine (A) = (0,0), puis de tracer un triangle vert sur la face ((S), (B), (C)).

Image

Pour cela il faudrait sans doute déterminer momentanément un nouveau système de référence (bleu) d'origine (B), d'abscisse confondue avec la demi-droite [BC), donc parallèle à l'axe des ordonnées du repère principal rouge, et dont l'axe des ordonnées du repère momentané soit confondu avec la demi-droite [Mbc,S), où Mbc est le milieu de BC donc inclinée à 60 degrés sur l'axe des abscisses du repère bleu.

Pour la suite du projet, le triangle vert doit être dessiné en utilisant le chemin (début) -- ++(60:\cote) -- ++(-60:\cote) -- cycle.

L'objectif final sera une pyramide de Sierpinski.

Image

Je n'arrive pas à finaliser les lignes de code pour calculer les arguments de \tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}.
Le code ci-dessous compile correctement. Seul le calcul faux.

Peut-on contourner cette difficulté ?

Code : Tout sélectionner

\input{./preambule-utf8.ltx}   
 
\begin{document}
 
	\newcommand{\DefinePoints}[1]{%
		\foreach \x/\y/\z/\name in {#1} {
			\coordinate (\name) at (\x, \y, \z);
		}
	}
	
\tdplotsetmaincoords{70}{120}%

	\begin{tikzpicture}	[ 
             tdplot_main_coords,		
             cube/.style={very thick,black},
              grid/.style={very thin,gray},
                           axis/.style={->,blue,thick},
           rotated axis/.style={->,purple,thick},
           line cap=round,
           line join=round,
           >=triangle 45,
           scale=3]
  
  % Dessiner les arêtes de la pyramide
  \draw[axis, tdplot_main_coords, red] (0,0,0) -- (4,0,0) node[anchor=south]{$x$};
 \draw[axis,  tdplot_main_coords, red] (0,0,0) -- (0,3,0) node[anchor=north west]{$y$};
  \draw[axis, tdplot_main_coords, red] (0,0,0) -- (0,0,3) node[anchor=west]{$z$};
  
  \def\cote{2}
\pgfmathsetmacro{\hauteur}{\cote * sqrt(2) * 0.5} 
\pgfmathsetmacro{\SMbc}{sqrt( (\cote)^2   -    (0.5*\cote)^2 }
\pgfmathsetmacro{\SMad}{\SMbc}
   
  \DefinePoints{
  	        0/                0/                      0/A, 
  	\cote/                0/                      0/B,
  	\cote/         \cote/                      0/C,
  	     0/          \cote/                     0/D,
  	0.5*\cote/  0.5*\cote/    \hauteur  /S,
  	0/                0/          \cote     /Z, 
 \cote/  0.5*\cote/    0/Mbc,
  0/  0.5*\cote/    0/Mad%
  }       
  
  \draw[ ] (A) -- (B) -- (C) -- (D) -- cycle;
  \foreach \point in {A, B, C, D} {
  	\draw  (S)  -- (\point);
  }
  
  \draw[ ]  (A) -- (S) -- (B);
  \draw[ ]   (B) -- (S) -- (C);
 
 \tdplotsetrotatedcoordsorigin{(B)}
 
% ---------------------------------------------------

% Lorsque le triangle vert est dessiné dans le repère bleu, il est "incliné" de 60 degrés par rapport au plan xy. Il n'est donc pas prarallèle au plan BAC 
% L'axe Ax'  du repère bleu doit être  parallèle à l'axe des y rouge (AB) 
% L'axe Ay' du repère bleu doit être incliné à 60 degrés c'est-à-dire parallèle à la médiane (S)  (Mbc)
% L'axe Az' doit etre orthogonal   aux  deux précédents Ax', Ay'

% Calculate \alpha (Rotation about the World X-Axis)
\pgfmathanglebetweenpoints%
{\pgfpointanchor{B}{center}}%
{\pgfpointanchor{S}{center}}
\let\alpha\pgfmathresult

% Calculate \beta (Rotation about the World Y-Axis)
\pgfmathanglebetweenpoints%
{\pgfpointanchor{C}{center}}  
{\pgfpointanchor{B}{center}}
\let\beta\pgfmathresult

% Calculate \gamma (Rotation about the World Z-Axis)
\pgfmathanglebetweenpoints%
{\pgfpointanchor{A}{center}}%
{\pgfpointanchor{S}{center}}
\let\gamma\pgfmathresult
 
 % Faute de mieux en attendant de trouver la réponse 
 % \def\alpha{0}
%  \def\beta{60}
 % \def\gamma{90}
 
 \tdplotsetrotatedcoordsorigin{(B)}
 
% \tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}
  \tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}

% ---------------------------------------------------

   	\begin{scope}[tdplot_rotated_coords]
 
 	% draw the rotated coordinate frame axes
 	\draw[rotated axis, blue, line width=1pt] (0,0,0) -- (3,0,0) node[anchor=west]{$x'$};
 	\draw[rotated axis, blue, line width=1pt]  (0,0,0) -- (0,4,0) node[anchor=south west]{$y'$};
 	\draw[rotated axis, blue, line width=1pt]  (0,0,0) -- (0,0,3) node[anchor=west]{$z'$};
 	
 	\draw (0,0,0) -- (\cote,0,0) -- (\cote, \cote, 0) -- (0,\cote,0) -- cycle ; 
 
 % Tracer le triangle vert avec un chemin relatif dans le plan (SBC) 	
  
  \draw[-, green, line width=2pt] (B) -- ++(60:\cote) -- ++(-60:\cote) ; %   -- cycle ; 
  % \draw[-, green, line width=2pt] (B) -- (0.5\cote, \SMbc) ;  
 	
 \end{scope} 
 
 \node at (1,-1, -2)  {alpha : \alpha } ; 
 \node at (1,-1, -2.25)  {beta  : \beta} ; 
 \node at (1,-1, -2.5)  {gamma : \gamma} ; 
		
		\foreach \n/\pos  in {S/above, A/{above left}, B/{above left}, C/below, D/{above right}, Z/right, Mbc/below}{
			\tkzDrawPoint (\n)
			\tkzLabelPoints[\pos](\n)           
		} 
 
	\end{tikzpicture}

\end{document}
Merci de m'aider à mettre fin à mon insomnie consécutive à mon incapacité à résoudre ce problème.
Pièces jointes
Capture d’écran 2023-10-06 à 18.53.05.png
dhenin
Utilisateur débutant
Utilisateur débutant
Messages : 2
Inscription : dimanche 08 octobre 2023, 08:31
Statut actuel : Autre

Re: Pyramide de Sierpinski (dplotsetrotatedcoords)

Message non lu par dhenin »

Voilà une solution satisfaisante :

Code : Tout sélectionner

\documentclass{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}

\begin{document}
 
% Décommenter si nécessaire  
%  \newcommand{\AxesPrincipaux}{}  % main_coords,	
%  \newcommand{\axesTournes}{}  % rotated axis,		 	 
%  \newcommand{\faciliteDeMiseAuPoint}{}


\tikzset{
	axis/.style={->,blue,thick},
	rotated axis/.style={->,purple,thick},
	base/.style={gray!60},
	line cap=round,
	line join=round,
	>=triangle 45,
	base/.style={gray!50}
}


	
	% Sur le modèle de tkz-euclide "\definePoints"
	\newcommand{\DefinePoints}[1]{%
		\foreach \x/\y/\z/\name in {#1} {
			\coordinate (\name) at (\x, \y, \z);
		}
	}
	
	% Le tout petir triangle de base 
	% #1 : position intiale, par ex : (X) 
	% #2 : mesure du côté du triangle 
	% #3  : couleur et autres styles en arguments  
	\newcommand\faisUn[3] {\fill[#3] #1  -- ++(-60:#2)  -- ++(-#2,0) -- cycle;
	}
	
	% Trois triangles "pleins" autour d'un triangle vide 
	% #1 : position intiale, par ex : (X) 
	% #2 : mesure du côté du triangle 
	% #3  : couleur et autres styles en arguments  
	\newcommand{\faisTrois}[3]{
		\coordinate  (X) at (#1) ;
		\coordinate  (tmpA) at (X) ;
		\def\coteA{#2}
		\faisUn{(X)} {\coteA}{#3}
		\coordinate (X) at ([shift={(-120:\coteA)}]X);
		\faisUn{(X)} {\coteA} {#3}
		\coordinate (X) at ([shift={(\coteA,0)}]X);
		\faisUn{(X)} {\coteA} {#3}
		\coordinate  (X) at (tmpA) ;
		
	}
	
	% Trois fois trois triangles "pleins" autour d'un triangle vide 
	% #1 : position intiale, par ex : (X) 
	% #2 : mesure du côté du triangle 
	% #3  : couleur et autres styles en arguments  
	\newcommand{\faisNeuf}[3]{
		\coordinate  (X) at (#1) ;
		\coordinate  (tmpB) at (X) ;
		\def\coteB{#2}
		
		\faisTrois{X}{\coteB}{#3}
		
		\coordinate (X) at ([shift={(-120:2*\coteB)}]X);
		
		\faisTrois{X}{\coteB}{#3}
		\coordinate (X) at ([shift={(2*\coteB,0)}]X);
		
		\faisTrois{X}{\coteB}{#3}
		
		\coordinate  (X) at (tmpB) ;
		
	}
	%  3 x trois fois  3 triangles "pleins" autour d'un triangle vide 
	% #1 : position intiale, par ex : (X) 
	% #2 : mesure du côté du triangle 
	% #3  : couleur et autres styles en arguments  
	\newcommand{\faisTroisNeuf}[3]{
		\coordinate  (X) at (#1) ;
		\coordinate  (tmpC) at (X) ;
		\def\coteC{#2}
		
		\faisNeuf{X}{\coteC}{#3}
		
		\coordinate (X) at ([shift={(-120:4*\coteB)}]X);
		\faisNeuf{X}{\coteC}{#3}
		
		\coordinate (X) at ([shift={(4*\coteB,0)}]X);
		\faisNeuf{X}{\coteC}{#3}
	}
	
	% ------------
	% Faire une face en fonction de 
	% #1 : orientation des abscisses selon la face 
	% #2 : Sommet en bas à gauche de la face (A ou B ou C ou D)
	% # 3 : couleur et autres style de la face
	% #4 : Etape  (niveau de découpage)
	\newcommand\faireFace[4]{
		
		\def\alpha{#1}
		%   \beta a été calculé une fois pour toute à l'initialisation 
		\def\gamma{90}
		
		% Origine en bas à droite du triangle 		
		\tdplotsetrotatedcoordsorigin{#2}
		
		\tdplotsetrotatedcoords{\alpha}{\beta}{\gamma}
		
		\begin{scope}[tdplot_rotated_coords]
			\ifdefined\axesTournes
			\draw[rotated axis, blue, line width=1pt] (0,0,0) -- (5,0,0) node[anchor=west]{$x'$};
			\draw[rotated axis, blue, line width=1pt]  (0,0,0) -- (0,4,0) node[anchor=south west]{$y'$};
			\draw[rotated axis, blue, line width=1pt]  (0,0,0) -- (0,0,3) node[anchor=west]{$z'$};
			\fi
			
			% C'est le haut du triangle qui sert à positionner le trangle 
			%  Quelque soit sa  taille 	 
			\coordinate  (X) at (S) ;
			
			\ifnum #4=4
			\def\cote{4} 	% Mesure de l'arette 		
			\def\coteDeco{0.25} % Mesure coté petit triangle 
			\faisTroisNeuf{X} {\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(-0.25*\cote,0)}]X);
			\coordinate (X) at ([shift={(-120:0.25*\cote)}]X);
			
			\faisTroisNeuf{X} {\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(0.25*\cote,0)}]X);
			\coordinate (X) at ([shift={(60:0.25*\cote)}]X);
			\faisTroisNeuf{X} {\coteDeco}{#3}
			\fi
			\ifnum #4=3
			\def\cote{4} 	% Mesure de l'arette 		
			\def\coteDeco{0.5} % Mesure coté petit triangle 
			
			\faisNeuf{X}{\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(-120:0.5*\cote)}]X);
			\faisNeuf{X}{\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(0.5*\cote,0)}]X);
			\faisNeuf{X}{\coteDeco}{#3}
			
			\fi
			
			\ifnum #4=2
			\def\cote{4} 	% Mesure de l'arette 		
			\def\coteDeco{1} % Mesure coté petit triangle 
			
			\faisTrois{X}{\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(-120:0.5*\cote)}]X);
			\faisTrois{X}{\coteDeco}{#3}
			
			\coordinate (X) at ([shift={(0.5*\cote,0)}]X);
			\faisTrois{X}{\coteDeco}{#3}
			
			\fi
			
			\ifnum #4=1
			
			\def\cote{4} 	% Mesure de l'arette 		
			\def\coteDeco{2} % Mesure coté petit triangle 
			
			\faisUn{(X)} {\coteDeco} {#3}
			
			\coordinate (X) at ([shift={(-120:0.5*\cote)}]X);
			\faisUn{(X)} {\coteDeco} {#3}
			
			\coordinate (X) at ([shift={(0.5*\cote,0)}]X);
			\faisUn{(X)} {\coteDeco} {#3}
			
			\fi
			
			\ifnum #4=0
			
			\def\cote{4} 	% Mesure de l'arette 		
			\def\coteDeco{4} % Mesure coté petit triangle 
			
			\faisUn{(X)} {\coteDeco} {#3}
			
			\fi
			
		\end{scope}
	} % Fin de command faireFace
	
	\tdplotsetmaincoords{70}{120}%
	
	% Il nous faudra 5 pyramides différentes 
	% #1 : Numéro de l'étape 
	%  #2 : Mesure de la pyramide 
	%  #3 : Mesure du côté du triangle (selon l'étape)  	
	\newcommand\faisLaPyramide[1]{
		\setbox1\hbox{
			\begin{tikzpicture}	[
				tdplot_main_coords,
				scale=0.35       % C'est ici qu'il fauy définir l'échelle ! 
				]
				
				% Dessiner les axes  principaux 
				\ifdefined\AxesPrincipaux
				\draw[axis, tdplot_main_coords, red] (0,0,0) -- (5,0,0) node[anchor=south]{$x$};
				\draw[axis,  tdplot_main_coords, red] (0,0,0) -- (0,5,0) node[anchor=north west]{$y$};
				\draw[axis, tdplot_main_coords, red] (0,0,0) -- (0,0,3) node[anchor=west]{$z$};
				\fi
				
				% --------    Initialisation de caractéristiques ----------
				\def\cote{4} 	% Mesure de l'arette 		
				
				\def\coteDeco{0.25} % Mesure coté petit triangle 
				% Mesure de la hauteur de la face printipale 			
				\pgfmathsetmacro{\SMbc} {sqrt( (\cote)^2   -    (0.5*\cote)^2 }
				% Mesure de la hauteur de la pyramide 
				\pgfmathsetmacro{\hauteur}   {sqrt( (\SMbc)^2   -    (0.5*\cote)^2 }
				
				% Mesure de l'angle d'une face avec la base 	    	
				\pgfmathsetmacro{\beta}{atan2(\hauteur, 0.5*\cote)}
				%  Les sommets et points utiles 		
				\DefinePoints{
					0/                0/                      0/A,
					\cote/                0/                      0/B,
					\cote/         \cote/                      0/C,
					0/          \cote/                     0/D,
					0.5*\cote/  0.5*\cote/    \hauteur  /S,
					\cote/  0.5*\cote/    0/Mbc%
				}
				% ------------------------------------------
				
				%  Base	 teintée 	
				\fill [base] (A) -- (B) -- (C) -- (D) -- cycle;
				
				\ifdefined\faciliteDeMiseAuPoint
				% Contour de la pyramide			
				\foreach \point in {A, B, C, D} {
					\draw  (S)  -- (\point);
				}
				
				\draw[ ]  (A) -- (S) -- (B);
				\draw[ ]   (B) -- (S) -- (C);
				\fi
				
				% 	\pgfmathsetmacro{\beta}{atan2(\hauteur, 0.5*\coteDeco)}
				
				% face avant droit  (DSA)	
				% On commence par une face cachée par l'avant  
				\faireFace{180} {(D)} {red!40}  {#1}   % La perspective déforme et trompe 
				
				% face avant droit  (DSA)	
				
				\faireFace{270}  {(A)} {red!50} {#1}    % La perspective déforme et trompe 		
				
				% face avant gauche (BSC)	
				
				\faireFace{0} {(B)}  {red!60} {#1}
				
				% face avant droit  (CSD)	
				
				\faireFace{90}  {(C)} {red!70} {#1}
				
				% ++++++++++++++
				
				\ifdefined\faciliteDeMiseAuPoint
				\foreach \n/\pos  in {S/above, A/{above left}, B/{above left}, C/below, D/{above right},   Mbc/below}{
					\tkzDrawPoint (\n)
					\tkzLabelPoints[\pos](\n)
				}
				\fi
				
			\end{tikzpicture}
		} % Fin de setbox1\hbox
	} % fin de command\faisLaPyramide
	
	\begin{tikzpicture}
		
		\faisLaPyramide{0}
		\node at (0,0) {\box1};
		
		\faisLaPyramide{1}
		\node at (2,0) {\box1};
		
		\faisLaPyramide{2}
		\node at (4,0) {\box1};
		
		\faisLaPyramide{3}
		\node at (6,0) {\box1};
		
		\faisLaPyramide{4}
		\node at (8,0) {\box1};
	\end{tikzpicture}
 
\end{document}
18_SierpinskiPyramide.pdf
(14.42 Kio) Téléchargé 204 fois
Bonne fin de journée.
MB
Administrateur
Administrateur
Messages : 8078
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: Pyramide de Sierpinski (dplotsetrotatedcoords)

Message non lu par MB »

Merci pour ce retour.
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.