Paramétrage de la perspective sous TikZ

Dans les schémas 3D sous TikZ, du choix de la perspective dépendra la qualité et le réalisme de l’illustration. Je vous donne ici un moyen de garantir la propreté des projections nécessaires à l’impression de perspective.

Exemple

Voici ci-après un exemple de paramétrage des axes 3D, comme on le fait habituellement :

\begin{tikzpicture}[x={(-0.5 cm,-0.3 cm)},y={(0.5 cm,-0.3 cm)},z={(0,0.5 cm)}]
	\draw[->] (0,0,0) -- (1,0,0) node[anchor=north east]{${x}$};
	\draw[->] (0,0,0) -- (0,1,0) node[anchor=north west]{${y}$};
	\draw[->] (0,0,0) -- (0,0,1) node[anchor=south]{${z}$};
\end{tikzpicture}

On obtient ainsi :
exemple

Objectif

L’objectif est donc de s’assurer que les axes soient paramétrés de façon réaliste. Sur la figure suivante, $latex (\boldsymbol{x}_1,\boldsymbol{y}_1,\boldsymbol{z}_1)$ est le repère que l’on souhaite utiliser pour la représentation tandis que $latex (\boldsymbol{x}_0,\boldsymbol{y}_0,\boldsymbol{z}_0)$ est le repère par défaut. On parle ici de perspective axonométrique.

Repère de référence (à gauche) et repère souhaité (à droite)

On cherche donc la transformation à appliquer au repère de référence pour aboutir au repère souhaité.

Les maths

On applique successivement les transformations suivantes (illustrées ci-après) :

  1. rotation d’un angle $latex \theta$ autour de $latex -\boldsymbol{x}$ (soit $latex -\theta$ autour de $latex \boldsymbol{x}$),
  2. rotation d’un angle $latex \phi$ autour de $latex \boldsymbol{-z}’$ (soit $latex -\phi$ autour de $latex \boldsymbol{z}’$), résultat de la transformation de $latex \boldsymbol{z}$ par la rotation précédente.
Figures de rotations
Figures de rotations

Soit $latex \mathbf{R}$ la matrice de rotation correspondant aux précédentes transformations. On a alors :

$latex
\mathbf{R}=\mathbf{R}_x\left(-\theta\right)\mathbf{R}_z\left(-\phi\right)$

$latex
\mathbf{R}=
\begin{bmatrix}
1 & 0 & 0\\
0 & \cos\theta & \sin\theta\\
0 &-\sin\theta & \cos\theta
\end{bmatrix}
\begin{bmatrix}
\cos\phi & \sin\phi & 0\\
-\sin\phi & \cos\phi & 0\\
0 & 0 & 1
\end{bmatrix}=
\begin{bmatrix}
\cos\phi & \sin\phi & 0\\
-\cos\theta\sin\phi & \cos\theta\cos\phi & \sin\theta\\
\sin\theta\sin\phi & -\sin\theta\cos\phi & \cos\theta
\end{bmatrix}$

L’objectif étant de dessiner le repère $latex (\boldsymbol{x}_1,\boldsymbol{y}_1,\boldsymbol{z}_1)$ en 2D (dans le plan de la feuille…), on va projeter les composantes de cette base dans $latex (\boldsymbol{x}_0,\boldsymbol{y}_0)$

$latex
\boldsymbol{x}_1=\begin{pmatrix}
\left(\mathbf{R}\boldsymbol{x}_0\right)\cdot\boldsymbol{x}_0=\cos\phi\\
\left(\mathbf{R}\boldsymbol{x}_0\right)\cdot\boldsymbol{y}_0=-\cos\theta\sin\phi
\end{pmatrix}$

$latex
\boldsymbol{y}_1=\begin{pmatrix}
\left(\mathbf{R}\boldsymbol{y}_0\right)\cdot\boldsymbol{x}_0=\sin\phi\\
\left(\mathbf{R}\boldsymbol{y}_0\right)\cdot\boldsymbol{y}_0=\cos\theta\cos\phi
\end{pmatrix}$

$latex
\boldsymbol{z}_1=\begin{pmatrix}
\left(\boldsymbol{R}\boldsymbol{z}_0\right)\cdot\boldsymbol{x}_0=0\\
\left(\boldsymbol{R}\boldsymbol{z}_0\right)\cdot\boldsymbol{y}_0=\sin\theta
\end{pmatrix}$

Code LaTeX

On connaît maintenant la transformation à appliquer aux coordonnées $latex (x,y,z)$ d’un point de l’espace pour le positionner dans le repère choisi pour une valeur de $latex (\theta,\phi)$ donnée.

On va donc définir un nouvel environnement (3dtikzpicture) dans lequel appliquer la transformation.

\newenvironment{3dtikzpicture}[3][]{
	\pgfmathsetmacro\xx{cos(#3)}
	\pgfmathsetmacro\xy{cos(#2)*sin(#3)}
	\pgfmathsetmacro\yx{-sin(#3)}
	\pgfmathsetmacro\yy{cos(#2)*cos(#3)}
	\pgfmathsetmacro\zy{sin(#2)}
	\begin{tikzpicture}[x={(\xx cm,\xy cm)},y={(\yx cm,\yy cm)},z={(0,\zy cm)},#1]
}{
	\end{tikzpicture}
}

Les arguments obligatoires sont l’angle $latex \theta$ et l’angle $latex \phi$. L’argument optionnel est passé à l’environnement tikzpicture (ex : scale=2, thick etc.).

Pour la figure avec les repères de référence et repère tourné (voir plus haut), ces derniers ont été dessinés avec le code suivant :

\begin{3dtikzpicture}{0}{0}
	\draw[->] (0,0,0) -- (1,0,0) node[pos=1.2]{$\e{x}$};
	\draw[->] (0,0,0) -- (0,1,0) node[pos=1.2]{$\e{y}$};
	\draw (0,0,0) -- (0,0,1) node[anchor=north]{$\e{z}$};
	\draw[red] (0.2,0,0) --(0.2,0.2,0)--(0,0.2,0)--(0,0.2,0.2)--(0,0,0.2)-- (0.2,0,0.2) --cycle;
\end{3dtikzpicture}	
\begin{3dtikzpicture}{60}{120}
	\draw[->] (0,0,0) -- (1,0,0) node[pos=1.2]{$\e[1]{x}$};
	\draw[->] (0,0,0) -- (0,1,0) node[pos=1.2]{$\e[1]{y}$};
	\draw[->] (0,0,0) -- (0,0,1) node[pos=1.2]{$\e[1]{z}$};
	\draw[red] (0.2,0,0) --(0.2,0.2,0)--(0,0.2,0)--(0,0.2,0.2)--(0,0,0.2)-- (0.2,0,0.2) --cycle;
\end{3dtikzpicture}

Pour aller plus loin

Si vous cherchez plus de possibilités de rotation (angles d’Euler par exemple), je vous invite à regarder du côté du package tikz-3dplot. Si vous souhaitez dessiner en perspective fuyante, je vous souhaite bien du courage

Note : les figures de rotations ont été réalisées depuis mon package RotationFigure.