Historique des modifications [retour]
cliquez ici pour masquer/afficher la révision 5
solution élégante et explications

14 Jul '22, 18:59

YannD's gravatar image

YannD
465410

# Solution Un environnement qui me semble adapté et plutôt commun est `tikzpicture` (issu du *package* `tikz`) qui peut donner des choses comme ceci : ## Solution plus élégante (ajoutée le 14 juillet 2022) \documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning}% pour le positionnement relatif \usetikzlibrary{decorations.pathreplacing}% pour les accolades % épaisseur des traits des cases \newlength{\colLineWidth} \setlength{\colLineWidth}{0.4pt} % largeur des cases \newlength{\colWidth} \setlength{\colWidth}{1cm} % longueur entre l'accolade et ce qu'elle embrasse \newlength{\accoSep} \setlength{\accoSep}{1.5mm} % longueur à enlever aux accolades de chaque côté \newlength{\accoRetrecie} \setlength{\accoRetrecie}{0.5mm} \addtolength{\accoRetrecie}{\colLineWidth}% pour que la longueur ci-dessus soit celle entre l'accolade et l'extérieur du trait de la case (augmenter \colLineWidth et commenter la ligne pour voir l'effet) % amplitude de l'accolade \newlength{\accoAmp} \setlength{\accoAmp}{2mm} % longueur entre l'accolade et son label \newlength{\accoLabelSep} \setlength{\accoLabelSep}{1mm} \addtolength{\accoLabelSep}{\accoAmp}% pour que la longueur ci-dessus soit celle entre la pointe (et non les extrémités) de l'accolade et le label % dessine une accolade au-dessus de deux points avec un label % #1 : point à gauche % #2 : point à droite % #3 : texte au dessus de l'accolade \newcommand{\accoladeDessus}[3]{% \draw [decorate,decoration={brace,amplitude=\accoAmp}] ([shift={(\accoRetrecie,\accoSep)}]#1) -- ([shift={(-\accoRetrecie,\accoSep)}]#2) node [midway,above=\accoLabelSep] {#3}; } % dessine une accolade en dessous de deux points avec un label % #1 : point à gauche % #2 : point à droite % #3 : texte en dessous de l'accolade \newcommand{\accoladeDessous}[3]{% \draw [decorate,decoration={brace,mirror,amplitude=\accoAmp}] ([shift={(\accoRetrecie,-\accoSep)}]#1) -- ([shift={(-\accoRetrecie,-\accoSep)}]#2) node [midway,below=\accoLabelSep] {#3}; } % dessine une colonne % #1 : nom de la colonne % #2 : hauteur de la colonne % #3 : options (pour positionner la colonne) \newcommand{\creerColonne}[3]{% \node (#1) [draw,line width=\colLineWidth,text width=\colWidth,text height=#2,#3] {}; } \begin{document} \begin{tikzpicture}[ inner sep=0mm, node distance=0mm, titre/.style={font=\bfseries}, ] %%%% %% INDUCTION 1 %%%% % colonnes \creerColonne{col1}{4cm}{} \creerColonne{col2}{5.5cm}{right=-\colLineWidth of col1.north east,anchor=north west} \creerColonne{col3}{7cm}{right=-\colLineWidth of col2.south east,anchor=south west} % contenu des colonnes \begin{scope}[every node/.style={rotate=90}] \node at (col1) {texte}; \node at (col2) {$a^2 + b^2 = c^2$}; \node at (col3) {texte}; \end{scope} % accolades \accoladeDessus{col1.north west}{col2.north east}{corégion} \accoladeDessous{col2.south west}{col3.south east}{région} % titre \node [titre,yshift=2.5cm] at (col2.north) {Induction 1}; %%%% %% INDUCTION 2 %%%% \begin{scope}[xshift=5cm] % colonnes \creerColonne{col1}{4cm}{}; \creerColonne{col2}{2.5cm}{right=-\colLineWidth of col1.north east,anchor=north west} \creerColonne{col3}{1.5cm}{right=-\colLineWidth of col2.south east,anchor=south west} % contenus des colonnes \node at (col3.center) {(3)}; \node at ([xshift=-\colWidth]col3.center) {(2)}; \node at ([xshift=-2\colWidth]col3.center) {(1)}; % accolades \accoladeDessus{col1.north west}{col2.north east}{corégion} \accoladeDessous{col2.south west}{col3.south east}{région} % titre \node [titre,yshift=2.5cm] at (col2.north) {Induction 2}; \end{scope} \end{tikzpicture} \end{document} ## Solution initiale \documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning}% pour le positionnement relatif \usetikzlibrary{decorations.pathreplacing}% pour les accolades \newlength{\caseStrokeWidth} \setlength{\caseStrokeWidth}{.4pt} \begin{document} \begin{tikzpicture}[inner sep=0mm,node distance=0mm,case/.style={draw=black,line width=\caseStrokeWidth},accolade/.style={decorate,decoration={brace,amplitude=2mm}},titre/.style={font=\bfseries}] \node (case1) [case,rotate=90,text width=4cm,minimum size=1cm,align=center] {texte}; \node (case2) [case,rotate=90,right=-\caseStrokeWidth of case1.south east,anchor=north east,text width=5.5cm,minimum size=1cm,align=center] {$a^2 + b^2 = c^2$}; \node (case3) [case,rotate=90,right=-\caseStrokeWidth of case2.south west,anchor=north west,text width=7cm,minimum size=1cm,align=center] {texte}; \draw [accolade] ([shift={(\caseStrokeWidth,2\caseStrokeWidth)}]case1.north east) -- ([shift={(-\caseStrokeWidth,2\caseStrokeWidth)}]case2.south east) node [midway,yshift=4mm] {corégion}; \draw [accolade] ([shift={(-\caseStrokeWidth,-2\caseStrokeWidth)}]case3.south west) -- ([shift={(\caseStrokeWidth,-2\caseStrokeWidth)}]case2.north west) node [midway,yshift=-4mm] {région}; \draw (case2.east) node [titre,yshift=2.5cm] {Induction 1}; \begin{scope}[shift={(5,0)}] \node (case1) [case,text width=1cm,text height=4cm,align=center] {}; \node (case2) [case,right=-\caseStrokeWidth of case1.north east,anchor=north west,text width=1cm,text height=2.5cm,align=center] {}; \node (case3) [case,right=-\caseStrokeWidth of case2.south east,anchor=south west,text width=1cm,text height=1.5cm] {}; \node at (case3.center) {(3)}; \node at ([xshift=-1cm]case3.center) {(2)}; \node at ([xshift=-2cm]case3.center) {(1)}; \draw [accolade] ([shift={(\caseStrokeWidth,2\caseStrokeWidth)}]case1.north west) -- ([shift={(-\caseStrokeWidth,2\caseStrokeWidth)}]case2.north east) node [midway,yshift=4mm] {corégion}; \draw [accolade] ([shift={(-\caseStrokeWidth,-2\caseStrokeWidth)}]case3.south east) -- ([shift={(\caseStrokeWidth,-2\caseStrokeWidth)}]case2.south west) node [midway,yshift=-4mm] {région}; \draw (case2.north) node [titre,yshift=2.5cm] {Induction 2}; \end{scope} \end{tikzpicture} \end{document} Il y a sûrement des manières plus élégantes pour le faire mais cela remplit le contrat. La troisième figure est laissée en exercice :wink:😉. # Explications ## `\usetikizlibrary` Les fonctionnalités du *package* `tikz` peuvent être étendues avec des librairies qui se chargent à l'aide de la commande `\usetikzlibrary` dans le préambule. Par exemple `\usetikzlibrary{decorations.pathreplacing}` permet entre autres de faire un trait en forme d'accolade. Au final `\usetikzlibrary` similaire à `\usepackage`. ## Options globales L'environnement `tikzpicture` admet un argument optionnel sous forme d'une liste de clés-valeurs, ce qui permet d'éviter d'écrire une option plusieurs fois à l'intérieur de l'environnement. \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[draw=red]% ici tous les chemins, sauf ordre contraire, seront en rouge \draw (0,0) circle (2cm); \end{tikzpicture} \end{document} ## `inner sep` C'est la longueur entre la boîte et le contenu d'un nœud : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \node [draw] at (0,0) {A}; \node [draw,inner sep=1cm] at (2,0) {B}; \end{tikzpicture} \end{document} ## `truc/.style` Lorsque l'on a plusieurs objets qui auront les mêmes options on peut créer une « super option », localement en argument optionnel de l'environnement `tikzpicture`, ou globalement en argument de la commande `\tikzset`. ### Localement \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[patate/.style={draw=orange,fill=yellow}] \draw [patate] (0,0) circle (2cm); \end{tikzpicture} \end{document} ### Globalement \documentclass{article} \usepackage{tikz} \tikzset{patate/.style={draw=orange,fill=yellow}} \begin{document} \begin{tikzpicture} \draw [patate] (0,0) circle (2cm); \end{tikzpicture} \end{document} ## `text width` et `align` Ces options de nœuds sont le plus souvent utilisées pour des paragraphes, `text width` est la longueur de la boîte contenant le texte et `align` l'alignement du texte : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \node [draw,text width=2cm] at (0,0) {Petit paragraphe bla bla bla bla}; \node [draw,text width=4cm,align=center] at (0,-2) {Petit paragraphe bla bla bla bla}; \node [draw,text width=5cm] at (0,-4) {Mot}; \node [draw,text width=5cm,align=center] at (0,-6) {Mot}; \end{tikzpicture} \end{document} ## `minimum size` Cette option permet de définir une largeur et une hauteur minimum pour la boîte d'un nœud, je l'ai utilisée pour avoir un largeur de colonne (mais qui correspond à la hauteur de la boîte en elle-même car on la tourne de 90°) d'un centimètre dans l'induction 1. \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \node [draw,minimum size=2cm] at (0,0) {A}; \node [draw,minimum size=0cm] at (0,-2) {B}; \node [draw,text width=5cm,align=center,minimum size=2cm] at (0,-4) {Mot}; \end{tikzpicture} \end{document} ## `text height` L'option `text height` permet de modifier la hauteur de la boîte d'un nœud, cela change seulement la hauteur de la boîte et pas la profondeur (qui est gérée par `text depth`). Pour ne pas trop m'embêter à placer le contenu des colonnes, j'ai d'abord dessiner des nœuds vides, puis j'ai placé du texte dedans : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[every node/.style={draw}] \node at (0,0) {A}; \node [text height=2cm] at (1,0) {B}; \node [text depth=2cm] at (2,0) {C}; \node [text height=2cm,minimum size=8mm] (D) at (3,0) {}; \node [draw=none] at (D) {D}; \end{tikzpicture} \end{document} ## Points cardinaux et positionnement simples Lorsque l'on crée un nœud avec un nom, Ti*k*z crée plusieurs coordonnées avec des points cardinaux qui correspondent aux extrémités de la boîte du nœud. Par défaut un nœud est centré sur le point qu'on lui donne (c'est le `at (x,y)`) mais on peut changer cela en utilisant `left`, `right`, `above`, `below` (et des combinaisons de ceux-ci) ou l'option `anchor` à qui l'on donnera comme valeur `east`, `west`, `south`, `north` (ou des combinaisons de celles-ci). Par exemple `left` signifie : « place mon nœud à gauche du point », et `anchor=east` signifie : « le pôle Est du nœud doit correspondre au point », ces deux instructions sont équivalentes. \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[every node/.style={draw}]% permet de passer draw en option de tous les node \node [draw,minimum size=4cm,lightgray] (A) at (0,0) {bla bla bla bla bla bla}; \fill [red] (A.center) circle (1pt) node [above] {(A.center)}; \fill [red] (A.north) circle (1pt) node [above] {(A.north)}; \fill [red] (A.south) circle (1pt) node [below] {(A.south)}; \fill [red] (A.west) circle (1pt) node [left] {(A.west)}; \fill [red] (A.east) circle (1pt) node [right] {(A.east)}; \fill [red] (A.north west) circle (1pt) node [above left] {(A.north west)}; \fill [red] (A.north east) circle (1pt) node [above right] {(A.north east)}; \fill [red] (A.south west) circle (1pt) node [below left] {(A.south west)}; \fill [red] (A.south east) circle (1pt) node [below right] {(A.south east)}; \node [draw,circle,minimum size=4cm,lightgray] (B) at (0,-7) {bla bla bla bla bla bla}; \fill [red] (B.center) circle (1pt) node [anchor=south] {(B.center)}; \fill [red] (B.north) circle (1pt) node [anchor=south] {(B.north)}; \fill [red] (B.south) circle (1pt) node [anchor=north] {(B.south)}; \fill [red] (B.west) circle (1pt) node [anchor=east] {(B.west)}; \fill [red] (B.east) circle (1pt) node [anchor=west] {(B.east)}; \fill [red] (B.north west) circle (1pt) node [anchor=south east] {(B.north west)}; \fill [red] (B.north east) circle (1pt) node [anchor=south west] {(B.north east)}; \fill [red] (B.south west) circle (1pt) node [anchor=north east] {(B.south west)}; \fill [red] (B.south east) circle (1pt) node [anchor=north west] {(B.south east)}; \end{tikzpicture} \end{document} ## Positionnement relatif et `node distance` Si l'on positionne relativement les nœuds, on n'utilisera (presque) pas les coordonnées absolues. On peut alors omettre les coordonnées du premier qui seront automatiquement `(0,0)`. On peut positionner un nœud relativement à un autre en utilisant `left of`, `above of`... L'option `node distance` est la distance entre le centre du premier nœud et le point d'ancrage du deuxième (le point « `anchor` ») : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[every node/.style={draw}] \node (A) {A}; \draw [orange] (0,0) circle (1cm); \draw [red] (0,-1.5) arc (-90:-130:1.5); \draw [red] (0,-1.5) arc (-90:-50:1.5); \node [left of=A] {left of};% par défaut anchor=center \node [right of=A,right] {right of}; % les deux lignes ci-dessous montre qu'il faut mettre `position of` avant `postion` ou `anchor=` \node [above left,above left of=A] {above left of};% la position n'est pas prise en compte \node [above right of=A,anchor=south west] {above right of};% la position est prise en compte \node [below of=A,anchor=north,node distance=1.5cm] {below of}; % etc. \node (B) at (5,0) {B}; \node [below of=B,below,node distance=0cm] {below of}; \end{tikzpicture} \end{document} Malheureusement on ne peut pas mettre `below of=B.south`, on a alors deux options. La première se déduit des explications précédentes : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture}[every node/.style={draw}] \node (B) at (5,0) {B}; \node [below,node distance=0cm] at (B.south) {C}; \end{tikzpicture} \end{document} La deuxième est plus facile à comprendre lorsque l'on lit le code mais requiert la librairie `positioning` : \documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning} \begin{document} \begin{tikzpicture}[every node/.style={draw}] \node (B) at (5,0) {B}; \node [below=0cm of B.south] {C}; \end{tikzpicture} \end{document} ## Chevauchement des boîtes des nœuds et `line width` On remarque en agrandissant les deux derniers exemples que les bords des boîtes de `B` et `C` ne sont pas confondues. Pour y remédier il suffit de connaître la largeur du trait et de mettre son opposé à la place de `0cm` dans `\node [below=0cm of B.south] {C};`. L'option `line width` permet de gérer l'épaisseur des traits : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \draw (0,0) -- (2,0); \draw [line width=2mm] (0,-1) -- (2,-1); \node [draw] at (4,0) {A}; \node [draw,line width=1mm] at (4,-1) {B}; \end{tikzpicture} \end{document} Ainsi le tour est joué et on peut même utiliser une longeur que l'on pourra faire varier : \documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning} \newlength{\malongueur} \setlength{\malongueur}{1mm} \begin{document} \begin{tikzpicture}[case/.style={draw,line width=\malongueur}] \node [case] (B) at (5,0) {B}; \node [case,below=-\malongueur of B.south] {C}; \end{tikzpicture} \end{document} ## `shift` et option `midway` Les options `xshift`, `yshift` et `shift` permettent de faire des translations. Les deux premières prennent une longueur en paramètre et la dernière des coordonnées, par exemple `shift={(2,3)}`. Les accolades sont importantes car si elles n'y sont pas Ti*k*Z va croire que ce sont deux paires de clés-valeurs : `shift=(2` et `3)`, ce qu'on ne veut pas. On peut placer ces options de façon « classique » ou directement après la parenthèse ouvrante de coordonnées. Cette dernière méthode est nécessaire pour les coordonnées comme `(A)` ou `(A.east)`. L'option de nœud `midway` permet de placer un nœud au milieu d'un trait : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \draw (0,0) node [above] {(0,0)} -- (3,0) node [above] {(2,0)}; \draw [yshift=2cm] (0,0) -- (3,0) node [above,midway] {\verb|yshift=2cm|}; \draw [shift={(0,-2)}] (0,0) -- (3,0) node [below,midway] {\verb|shift={(0,-2)}|}; \node [draw,minimum size=2cm] (A) at (6,0) {A}; \fill [red,xshift=1cm] (A.east) circle (2pt);% loupé \fill [teal] ([xshift=1cm]A.east) circle (2pt);% réussi \fill ([shift={(1,1)}]A.north east) circle (2pt); \end{tikzpicture} \end{document} ## Accolade Pour dessiner un trait en forme d'accolade on a besoin de la librairie `decorations.pathreplacing`. On peut gérer sa largeur (pas celle du trait) avec l'option `amplitude` et son « sens » avec l'option `mirror` ou en échangeant les coordonnées : \documentclass{article} \usepackage{tikz} \usetikzlibrary{decorations.pathreplacing} \begin{document} \begin{tikzpicture} \draw [decorate,decoration={brace}] (0,0) -- (3,0); \draw [yshift=-2cm,decorate,decoration={brace,amplitude=1cm}] (0,0) -- (3,0); \draw [yshift=-4cm,decorate,decoration={brace,amplitude=2mm,mirror}] (0,0) -- (3,0); \draw [yshift=-6cm,decorate,decoration={brace,amplitude=2mm}] (3,0) -- (0,0); \end{tikzpicture} \end{document} ## Environnement `scope` Il permet de passer une option à tout ce qui est à l'intérieur. C'est utile pour éviter la répétition de code et lorsque les `trucs/.style` sont moins adaptés : \documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \draw (0,0) -- (0,3) -- (3,3) -- (3,0) -- cycle; \begin{scope}[line width=1mm,red,xshift=5cm] \draw (0,0) -- (0,3) -- (3,3) -- (3,0) -- cycle; \fill (0,0) circle (1cm); \end{scope} \end{tikzpicture} \end{document}
cliquez ici pour masquer/afficher la révision 4
code inutile

04 Jul '22, 20:52

YannD's gravatar image

YannD
465410

Un environnement qui me semble adapté et plutôt commun est `tikzpicture` (issu du *package* `tikz`) qui peut donner des choses comme ceci : \documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning}% pour le positionnement relatif \usetikzlibrary{decorations.pathreplacing}% pour les accolades \newlength{\caseStrokeWidth} \setlength{\caseStrokeWidth}{.4pt} \begin{document} \begin{tikzpicture}[inner sep=0mm,node distance=0mm,case/.style={draw=black,line width=\caseStrokeWidth},accolade/.style={decorate,decoration={brace,amplitude=2mm}},titre/.style={font=\bfseries}] \node (case1) [case,rotate=90,text width=4cm,minimum size=1cm,align=center] {texte}; \node (case2) [case,rotate=90,right=-\caseStrokeWidth of case1.south east,anchor=north east,text width=5.5cm,minimum size=1cm,align=center] {$a^2 + b^2 = c^2$}; \node (case3) [case,rotate=90,right=-\caseStrokeWidth of case2.south west,anchor=north west,text width=7cm,minimum size=1cm,align=center] {texte}; \draw [accolade] ([shift={(\caseStrokeWidth,2\caseStrokeWidth)}]case1.north east) -- ([shift={(-\caseStrokeWidth,2\caseStrokeWidth)}]case2.south east) node [midway,yshift=4mm] {corégion}; \draw [accolade] ([shift={(-\caseStrokeWidth,-2\caseStrokeWidth)}]case3.south west) -- ([shift={(\caseStrokeWidth,-2\caseStrokeWidth)}]case2.north west) node [midway,yshift=-4mm] {région}; \draw (case2.east) node [titre,yshift=2.5cm] {Induction 1}; \begin{scope}[shift={(5,0)}] \node (case1) [case,text width=1cm,text height=4cm,align=center] {}; \node (case2) [case,right=-\caseStrokeWidth of case1.north east,anchor=north west,text width=1cm,text height=2.5cm,align=center] {}; \node (case3) [case,right=-\caseStrokeWidth of case2.south east,anchor=south west,text width=1cm,text height=1.5cm] {}; \node [align=center] at (case3.center) {(3)}; \node [align=center] at ([xshift=-1cm]case3.center) {(2)}; \node [align=center] at ([xshift=-2cm]case3.center) {(1)}; \draw [accolade] ([shift={(\caseStrokeWidth,2\caseStrokeWidth)}]case1.north west) -- ([shift={(-\caseStrokeWidth,2\caseStrokeWidth)}]case2.north east) node [midway,yshift=4mm] {corégion}; \draw [accolade] ([shift={(-\caseStrokeWidth,-2\caseStrokeWidth)}]case3.south east) -- ([shift={(\caseStrokeWidth,-2\caseStrokeWidth)}]case2.south west) node [midway,yshift=-4mm] {région}; \draw (case2.north) node [titre,yshift=2.5cm] {Induction 2}; \end{scope} \end{tikzpicture} \end{document} Il y a sûrement des manières plus élégantes pour le faire mais cela remplit le contrat. La troisième figure est laissée en exercice :wink:
cliquez ici pour masquer/afficher la révision 3
code inutile

04 Jul '22, 20:51

YannD's gravatar image

YannD
465410

cliquez ici pour masquer/afficher la révision 2
oubli mot

04 Jul '22, 17:51

YannD's gravatar image

YannD
465410

cliquez ici pour masquer/afficher la révision 1

04 Jul '22, 17:50

YannD's gravatar image

YannD
465410