1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
|
\chapter{Dessiner avec \TikZ{}}
\label{chap-tikz}\lettrine{P}{our} faire des dessins, graphes, schémas, etc. avec \LaTeX{} sans avoir aucune contrainte quant au moteur de compilation, c'est d'utiliser \TikZ{}.
Si, comme moi, tu étais un habitué de PSTricks, il peut sembler déroutant de passer à \TikZ{} mais, avec la pratique, il devient facile de réaliser simplement quelques figures. Mais ce n'est pas tout : \TikZ{} est un bon compromis à PSTricks.
Si la prise en main peut paraître compliquée de prime abord, son utilisation finit par devenir intuitive très rapidement. Ce package offre énormément de possibilités, comme tu vas pouvoir le découvrir. \\
Et si jamais tu t'intéresses à la documentation officielle\footnote{Disponible sur le site du CTAN, directement sur : \url{http://www.ctan.org/pkg/pgf}.}, sache qu'il faut mieux aller d'abord regarder le sommaire ou l'index. Avec plus de 1~000 pages d'aide et de code, elle est plutôt bien fournie !
\section{Démarrer sous \TikZ{}}
\subsection*{Règles de base}
Tu vas difficilement pouvoir utiliser \TikZ{} si tu ne charges pas le package associé : \verb?tikz?. Comme nous le verrons plus tard, si tu dois charger des fonctionnalités supplémentaires de \TikZ{}, il faut utiliser la commande \verb?\usetikzlibrary{<nom-bibliotheque>}?, de préférence juste après avoir chargé le package \verb?tikz?.
Quant au dessin en lui-même, tout comme pour PSTricks, il faut charger un environnement spécifique. Ici, il se nomme \verb?tikzpicture?, et n'a pas besoin d'options supplémentaires (comme la taille du cadre sous PSTricks). En effet, \TikZ{} produit toujours le résultat le plus compact possible, comme nous le verrons dans un exemple juste après.
\begin{regles}{La règle capitale}
\textbf{Il existe une règle capitale sous \TikZ{} :} chaque commande propre à \TikZ{} se termine par un point-virgule ``\verb?;?''. Toujours. C'est le seul point important à retenir, sous peine de ne pas comprendre pourquoi ton code ne fonctionne pas.
\end{regles}
Sous \TikZ{}, s'il est plus courant de travailler avec des coordonnées cartésiennes $(x,y)$, sache aussi que les coordonnées polaire $(\theta:R)$ sont disponibles, écrites dans le même format que précédemment.
Il est aussi possible de définir des points, avec la commande \verb?\coordinate?. Sa syntaxe est la suivante, même si nous aurons l'occasion de revenir sur cette commande par la suite :
\begin{code}{}
\coordinate (<nom>) at (<coord>);
\end{code}
\subsection*{Un premier dessin}
Pour commencer en douceur, le tracé d'un trait sous \TikZ{} se fait de la manière suivante :
\begin{code}{}
\draw (x0,y0) -- (x1,y1);
\end{code}
La commande \verb?\draw? annonce un tracé. Les points à relier par un trait sont donc séparés par un double tiret ``\verb?--?''. Notons aussi au passage l'utilisation du point-virgule ``\verb?;?'' en fin de ligne, comme annoncé.
Il existe des fonctions propres à \TikZ{} pour tracer un rectangle ou un cercle. Il faut continuer d'utiliser la commande \verb?\draw? au préalable :
\begin{code}{}
\draw (x0,y0) rectangle (x1,y1);
\draw (x,y) circle (R);
\end{code}
Il est aussi possible d'augmenter l'épaisseur du trait ou de changer sa couleur grâce à des options à introduire entre crochets ``\verb?[]?'', de la manière suivante :
\begin{code}{}
\draw[<options>] ...;
\end{code}
\vspace{\baselineskip}
\emph{Je ne vais pas commencer à lister toutes les options possibles et envisageables.} Les plus basiques sont présentées ci-après. Les autres sont à chercher en fonction des besoins. Bien, voici un premier exemple pour avoir un aperçu concret des bases :
\begin{codetikz}{Démarrer sous \TikZ{}}
% Ajout au PREAMBULE
%\usepackage{tikz}
TikZ produit toujours le résultat le plus compact possible : \\
% Rendu final identique entre les 2 codes
\hspace*{\fill}
\begin{tikzpicture}
\draw (0,0) -- (1,1); % Trait entre (0,0) et (1,1)
\end{tikzpicture}
\hfill
\begin{tikzpicture}
\draw (2,2) -- (3,3); % Trait entre (2,2) et (3,3)
\end{tikzpicture}
\hspace*{\fill}
\end{codetikz}
\begin{codetikz}{Des formes simples}
\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}
\hfill
\begin{tikzpicture}
\draw (0,0) rectangle (2,3);
\end{tikzpicture}
\hfill
\begin{tikzpicture}
\draw (1,1) circle (0.5);
\end{tikzpicture}
\hfill
\begin{tikzpicture}
\draw circle (1.3);
% Si coordonnées vides, (0,0) par défaut
\end{tikzpicture}
\end{codetikz}
\begin{attention}{Une question ?}
\og Entre tes rectangles et tes cercles, l'origine $(0,0)$ n'est jamais au même endroit. Quelle est cette diablerie ? \fg{} \\
En effet, je comprends ton questionnement. J'ai pris le parti pour ces exemples d'utiliser des environnements \verb?tikzpicture? distincts pour chaque forme et pour pouvoir les espacer.
Comme \TikZ{} produit le résultat le plus compact et l'affiche sur la même ligne de base (environnement ``alignés'' ici), les origines sont décalées. Tu peux constater que tout est en ordre si je réunis toutes les commandes dans un même dessin :
\begin{codedisplay}{Utilisation d'un seul environnement}
\begin{tikzpicture}
\draw (0,0) rectangle (1,1);
\draw (0,0) rectangle (2,3);
\draw (1,1) circle (0.5);
\draw circle (1.3);
\end{tikzpicture}
\end{codedisplay}
\end{attention}
Reprenons avec d'autres exemples minimalistes, pour te montrer les options de base de \TikZ{} :
\begin{codetikz}{Un peu de couleur}
\hspace*{\fill}
\begin{tikzpicture}
% Forme courte et implicite
\draw[blue] (0,0) -- (1,1);
% Forme complète (nom option)
\draw[color = orange] (2,1) -- (3,0);
\end{tikzpicture}
\hfill
\begin{tikzpicture}
% Idem pour un contour (fermé)
\draw[red] (0,0) rectangle (1,1);
\draw[color = green] (2,1) rectangle (3,0);
% Autre possibilité (nuancer avec le remplissage)
\draw[draw = purple] (4,0) rectangle (5,1);
\end{tikzpicture}
\hspace*{\fill}
\end{codetikz}
\begin{codetikz}{Un peu de remplissage}
% Ligne 1
\begin{center}
\begin{tikzpicture}
% Remplissage rouge avec contour noir (par défaut)
\draw[fill = red] (0,0) rectangle (1,1);
% Remplissage pur (sans contour)
\fill[color = green] (2,1) rectangle (3,0);
\fill[fill = purple] (4,0) rectangle (5,1);
\end{tikzpicture}
\end{center}
% Ligne 2
\begin{center}
\begin{tikzpicture}
\draw[red, fill = blue] (0.5,0.5) circle (0.5);
\draw[draw = green, fill = orange] (2.5,0.5) circle (0.5);
% Nouvelle commande : contour et remplissage
\filldraw (4.5,0.5) circle (0.5);
\filldraw[brown] (6.5,0.5) circle (0.5);
% Personnalisation toujours possible
\filldraw[pink, draw = gray] (8.5,0.5) circle (0.5);
\end{tikzpicture}
\end{center}
\end{codetikz}
Nous pouvons constater que si une couleur seule est renseignée, \TikZ{} l'associe automatiquement à l'option \verb?draw?. Il existe même un choix supplémentaire pour indiquer qu'il ne faut pas mettre de couleur\footnote{Le fond n'est pas toujours blanc donc choisir \verb?white? n'est pas toujours judicieux.} : \verb?draw = none? ou \verb?fill = none?.
\begin{codetikz}{Changement d'épaisseur et de trait}
\begin{center}
\begin{tikzpicture}
% Epaisseur du trait : line width = <longueur>
\draw[line width = 1.3mm] (0,0) -- (1,1);
\draw[line width = 5pt] (2,1) -- (3,0);
% Unité par défaut (options) : le point "pt"
\draw[line width = 8] (4,0) -- (5,1);
% N.B. --> unité par défaut (coordonnées) : "cm"
\end{tikzpicture}
\end{center}
\begin{center}
\begin{tikzpicture}
% Tailles prédéfinies
\draw[thin] (0,0) -- (1,1);
% Nouveau trait : tiret
\draw[thick, dashed] (2,1) -- (3,0);
% Nouveau trait : en pointillé
\draw[ultra thick, dotted] (4,0) -- (5,1);
\end{tikzpicture}
\end{center}
\end{codetikz}
\begin{attention}{Renseigner les options dans le \emph{bon ordre}}
\TikZ{} lit les options indiquées de gauche à droite et les applique une par une, dans cette ordre de lecture. Sur le PDF, le remplissage des options est donc à faire en LIFO : \textit{Last In First Out} soit \og dernier arrivé premier servi \fg{} !
Tu peux t'en rendre compte très facilement avec le cas suivant :
\begin{codetikz}{Exemple}
\begin{center}
\begin{tikzpicture}
% Cas 1
\filldraw[pink, draw = gray, line width = 3pt] (0,0) circle (0.5);
% Cas 2 <> Cas 1
\filldraw[draw = gray, line width = 3pt, pink] (2,0) circle (0.5);
\end{tikzpicture}
\end{center}
\end{codetikz}
\end{attention}
Tu as tout compris ? Il existe plein d'options extrêmement pratiques mais la couleur et l'épaisseur du trait sont généralement celles les plus couramment utilisées au début. Il existe aussi des épaisseurs prédéfinies, qui fonctionnent très bien et évitent de perdre du temps à trouver la ``bonne'' épaisseur :
\begin{itemize}[label = \ding{213}]
\begin{multicols}{2} \raggedcolumns
\item \verb?ultra thin? : 0.1pt ;
\item \verb?very thin? : 0.2pt ;
\item \verb?thin? : 0.4pt (défaut) ;
\item \verb?semithick? : 0.6pt ;
\item \verb?thick? : 0.8pt ;
\item \verb?very thick? : 1.2pt ;
\item \verb?ultra thick? : 1.6pt.
\end{multicols}
\end{itemize}
Essayons maintenant de tracer des figures un peu plus complexes désormais, avec des coordonnées polaires pour changer un peu et les manipuler.
\section{Un polygone régulier}
Je pense que tu dois avoir déjà entendu parler d'un polygone régulier. Pour faire simple et éviter de faire mon pédant trop longtemps, il s'agit d'une figure géométrique fermée, à $N$ côtés de même longueur.
Une façon très simple d'en créer consiste à passer par des coordonnées polaires. En effet, les sommets $S_i$ d'un polygone régulier sont tous placés sur un cercle de centre $O$ quelconque, de rayon $R$ et la droite $(OS_i)$ forme un angle de $\theta_i = \frac{i \times 360}{N}$ avec l'axe des abscisses.
Les coordonnées polaires du sommet $S_i$ s'écrivent donc naturellement $(\theta_i:R)$.\\
Pour revenir sur l'utilisation de \TikZ{}, il faut savoir que toute figure définie par des traits et dont le point d'arrivée coïncide avec le point de départ (figure fermée) doit se conclure de la manière suivante : \verb?-- cycle;?.
Cette commande permet de proprement fermer la figure. Je te laisse aller faire des recherches ou des essais pour voir la différence avec une fermeture manuelle. Sinon, un petit exemple fait main, parce que cela me fait plaisir :
\begin{figure}[H]
\begin{minipage}{0.45\linewidth}
\centering
%\shorthandoff{;}
\begin{tikzpicture}[spy scope = {magnification = 5, size = 1.5cm}, every spy in node/.style = {magnifying glass, circular drop shadow, fill = white, draw, ultra thick, cap = round}]
\draw[thick] (1,1) -- (-2,2) -- (-3,0) -- cycle;
\spy [green!50!black] on (1,1) in node;
\end{tikzpicture}
%\shorthandon{;}
\subcaption{Ce qu'il faut faire (fermeture avec \texttt{cycle})}
\end{minipage}
\hfill
\begin{minipage}{0.45\linewidth}
\centering
%\shorthandoff{;}
\begin{tikzpicture}[spy scope = {magnification = 5, size = 1.5cm}, every spy in node/.style = {magnifying glass, circular drop shadow, fill = white, draw, ultra thick, cap = round}]
\draw[thick] (1,1) -- (-2,2) -- (-3,0) -- (1,1);
\spy [red] on (1,1) in node;
\end{tikzpicture}
%\shorthandon{;}
\subcaption{Ce qu'il ne faut \textbf{pas} faire (fermeture manuelle)}
\end{minipage}
\end{figure}
Bien, arrêtons-nous là concernant les détails et considérations techniques. Allons plutôt dessiner un polygone régulier, comme un triangle équilatéral, pour commencer simplement :
\begin{codetikz}{Un triangle équilatéral}
% Triangle équilatéral, inscrit dans un cercle de rayon R
% Coordonnées polaires ==> centre (0,0)
\begin{center}
\begin{tikzpicture}
% Rayon R choisi arbitrairement à 2cm
\draw (90:2) -- (210:2) -- (330:2) -- cycle;
% Une autre possibilité
\draw[green] (60:2) -- (180:2) -- (300:2) -- cycle;
\draw[red] circle (2); % Pas de centre ==> (0,0) par défaut
\end{tikzpicture}
\end{center}
\end{codetikz}
Avouons que, dans ce cas de figure, l'utilisation des cordonnées polaire est plus pratique que de devoir placer 2 points et calculer la position du dernier, surtout si les calculs ne donnent pas une valeur exacte. Ici, notre triangle est bel et bien équilatéral. \\
Le tracé peut aussi s'envisager avec des points définis à l'avance :
\begin{codetikz}{Définir des points}
\begin{center}
\begin{tikzpicture}
\coordinate (A) at (30:2);
\coordinate (B) at (150:2);
\coordinate (C) at (270:2);
\draw (A) -- (B) -- (C) -- cycle;
\end{tikzpicture}
\end{center}
\end{codetikz}
\section{Automatiser les dessins}
\subsection*{Coordonnées absolues et relatives}
Bon, tracer un triangle équilatéral, c'est bien. Tracer un hexagone, avec un copier-coller et un peu de patience, c'est faisable. Un tridécagone (polygone régulier à 13 côtés)\dots{} bon, rien d'impossible mais le copier-coller et les modifications ne constituent clairement pas une solution optimale !
Fort heureusement, il existe le principe des coordonnées absolues et relatives. \\
Pour faire simple, tracer un dessin grâce à une série de coordonnées absolues revient à connaître les positions de toutes les coordonnées par rapport à un repère, l'origine $(0,0)$ généralement mais il peut aussi s'agir d'un autre point.
Avec les coordonnées relatives, peu importe la position exacte de tous les points : il suffit juste de connaître la position d'un point par rapport à un autre ! \\
Sous \TikZ{}, les coordonnées absolues ne requiert aucune option spécifique, hormis la position du point. Les coordonnées relatives sont facilement reconnaissables grâce au ``\verb?++?'' et il existe un mix des deux, un peu subtil, qui utilise un ``\verb?+?''. L'aide officielle est assez explicite à ce sujet : \begin{quote}
{\huge\bfseries\color{gray!75}\og}
You can add a single + sign in front of a coordinate or two of them as in +(1cm,0cm) or ++(0cm,2cm). Such coordinates are interpreted differently.
The first form means ``1cm upwards from the previous specified position'' ; the second means ``2cm to the right of the previous specified position, \textbf{making this the new specified position.}''
{\hfill\huge\bfseries\color{gray!75}\fg}
\end{quote}
Concrètement, le tracé \verb?(A) --+ (xB,yB) --+ (xC,yC)? définit les points \verb?B? et \verb?C? par rapport au point \verb?A?.
Par contre, le tracé \verb?(A) --++ (xB,yB) --++ (xC,yC)? définit le point \verb?B? par rapport au point \verb?A? puis le point \verb?C? par rapport au point \verb?B? (nouvelle origine pour le déplacement suivant). \\
Bien, je pense qu'un petit exemple ne sera pas de trop pour aborder cette notion :
\begin{codetikz}{Coordonnées absolues et relatives}
% Je reviendrai sur les "node" par la suite
% Ici, ils permettent d'avoir un point de repère pour distinguer le départ du tracé (en rouge) de sa fin (en bleu)
% Sans les + ou ++
\begin{tikzpicture}
\draw[gray, dotted] (0,-1) grid (3,1); % Une trame de fond, pour aider
\draw (0,0) node[circle, fill = red, inner sep = 2pt] {} -- (1,1) -- (2,0) -- (0,-1) node[circle, fill = blue, inner sep = 2pt] {}; % Le point de départ est toujours le point à partir duquel est appliqué le déplacement
\end{tikzpicture}
\hfill
% Avec le +
\begin{tikzpicture}
\draw[gray, dotted] (0,-1) grid (3,1); % Une trame de fond, pour aider
\draw (0,0) node[circle, fill = red, inner sep = 2pt] {} -- (1,1) --+ (2,0) --+ (0,-1) node[circle, fill = blue, inner sep = 2pt] {}; % Le dernier point sans "+" -- (1,1) ici -- est toujours le point à partir duquel est appliqué le déplacement
\end{tikzpicture}
\hfill
% Avec le ++
\begin{tikzpicture}
\draw[gray, dotted] (0,-1) grid (3,1); % Une trame de fond, pour aider
\draw (0,0) node[circle, fill = red, inner sep = 2pt] {} --++ (1,1) --++ (2,0) --++ (0,-1) node[circle, fill = blue, inner sep = 2pt] {}; % Chaque nouveau point est le point de départ pour le déplacement d'après
\end{tikzpicture}
\end{codetikz}
Et cette méthode s'applique aussi pour les coordonnées polaires ! Appliquons alors cette découverte pour nos polygones réguliers. Après tout, il s'agit de prendre le point précédent et de le faire pivoter du bon angle :
\begin{codetikz}{Coordonnées relatives polaires}
% Cas d'un triangle équilatéral
\begin{tikzpicture}
\draw (0,0) -- (2,0) --++ (120:2) -- cycle;
\end{tikzpicture}
\hfill
% Cas d'un carré
\begin{tikzpicture}
\draw (0,0) -- (2,0) --++ (90:2) --++ (180:2) -- cycle;
\end{tikzpicture}
\hfill
% Cas d'un pentagone
\begin{tikzpicture}
\draw (0,0) -- (2,0) --++ (72:2) --++ (144:2) --++ (216:2) -- cycle;
\end{tikzpicture}
\end{codetikz}
Un exemple plus concret parlera peut-être à certains :
\begin{codetikz}{Un peu de physique}
% Ou comment simplifier le tracé d'un amortisseur
\begin{center}
\begin{tikzpicture}
\coordinate (O) at (0,0); % Possibilité de changer le 0,0 en argument d'une nouvelle commande...
\draw (O) --++ (2,0) --++ (0,-1) --++ (2,0) ++ (-2,1) --++ (0,1) --++ (2,0) node[above left] {\Large{}$\mu$} ++ (-1,0) --++ (0,-2) ++ (0,1) --++ (2,0);
% Utilisation de "++" sans "--" pour déplacer la coordonnée relative (on rebrousse chemin dans le tracé) sans tracer un trait
\end{tikzpicture}
\end{center}
\end{codetikz}
\begin{attention}{Une question ?}
\og Ton astuce est amusante pour tracer le polygone en polaire ou l'amortisseur mais ce n'est toujours pas pratique. Il faut quand même changer à la main les valeurs pour chaque polynôme\dots{} \fg{} \\
En effet\dots{} mais j'allais justement annoncer une magnifique solution automatisée !
\end{attention}
\subsection*{Variables et boucle \verb?for?}
Il existe trois outils que j'ai découverts suite à mon passage à \TikZ{} et qui se révèlent très utiles pour automatiser le tracé de dessins :
\begin{itemize}[label = \ding{213}]
\item \textbf{la définition de variable :} tu peux créer toi-même ta propre variable sous \LaTeX{}\footnote{Très exactement, il s'agit d'une macro. J'apporterai sûrement un correctif et une explication plus poussée lors de la prochaine mise à jour de ce guide et après quelques recherches.}. Appliquée à \TikZ{}, tu peux l'associer en tant que nombre (nombre de côtés d'un polygone régulier par exemple) ou en tant que longueur (rayon du cercle dans lequel le dit polygone est inscrit).
Il suffit d'utiliser la commande suivante :
\begin{code}{}
\def\nom{valeur}
\end{code}
\item \textbf{le calcul de nouvelles variables :} propre à \TikZ{}, cette possibilité peut parfois servir.
Par exemple, nous souhaitons dessiner un polygone régulier inscrit dans un cercle de rayon fixé, sans connaître la valeur d'un côté (même si c'est bien plus simple de considérer la taille d'un cercle pour l'affichage).
Si tu désires avoir un polygone avec une taille d'arête bien spécifique, il faut calculer le rayon ! Pour ce faire, il faut alors utiliser la commande :
\begin{code}{}
\pgfmathsetmacro\nom{<calcul>}
\end{code}
Il est aussi possible d'utiliser des variables déjà définies pour les intégrer dans le calcul. Les possibilités offertes deviennent alors très intéressantes ;
\item \textbf{la boucle \verb?for? :} comme avec un langage de programmation, il est possible d'indiquer à \LaTeX{}, et plus particulièrement à \TikZ{} dans notre cas, des tâches répétitives. La formulation est la suivante :
\begin{code}{}
\foreach \<var> in {1,...,N} {<boucle>}
\end{code}
J'ai mis \verb?{1,...,N}? pour l'exemple générique mais tu peux mettre n'importe quelle valeur numérique, comme \verb?{2,3,4}?, ou même des lettres ! C'est des fois pratique pour jongler avec des coordonnées. \\
\end{itemize}
En guise d'exemple, voici une solution simple qui fonctionne. Il y a sûrement encore moyen de l'améliorer, comme permettre à chaque trait d'avoir une couleur différente (avec \verb?cycle? en fin de ligne sinon c'est moche) mais elle fonctionne déjà plutôt bien :
\begin{codetikz}{Une solution automatisée}
% Un polygone régulier
\begin{center}
\begin{tikzpicture}
% Paramétrage
\def\poly{13} % Nombre entier supérieur à 1
% Limite de calcul LaTeX fixée à 16 383...
\pgfmathtruncatemacro\polyg{\poly - 1}
\def\R{2} % 0.13\linewidth est aussi une distance
% Tracé du polygone
\draw[orange] (90:\R) \foreach \i in {1,...,\polyg} {-- (90-\i/\poly*360:\R)} -- cycle; % Usage de \polyg pour pouvoir bien fermer avec "cycle"
\end{tikzpicture}
\end{center}
\end{codetikz}
\begin{conseil}{La gestion des unités}
Il peut arriver que tu définisses une variable mais que sa valeur ne donne pas le résultat attendu, en terme de taille. Par exemple, un rayon \verb?\def\R{50}? de 50pt ou 50mm au lieu de 50cm par défaut, un peu grand, surtout sur une feuille A4 ; ou encore, une épaisseur de trait \verb?\def\sep{13}? de 13mm au lieu de 13pt par défaut.
Seulement, écrire \verb?circle (\R{}pt)? ou \verb?line width = \sep mm? ne fonctionne pas toujours car \LaTeX{} n'arrive pas à combiner une variable avec du texte\dots{} \\
Heureusement, il existe donc un moyen très simple de résoudre ce problème. Il faut définir une variable unité : \verb?\def\unit{<unité>}?. Par exemple, nous pouvons écrire \verb?\def\unit{pt}? ou \verb?\def\mm{mm}? s'il y a plusieurs unités et que tu ne veux pas les confondre.
Il faut ensuite écrire, par exemple, \verb?circle (\R\unit)? ou \verb?line width = \sep\mm?, et le tour est joué !
\end{conseil}
\begin{attention}{Limite de calcul sous \TikZ{}}
Avec les commandes \verb?\def? et \verb?\pgfmathsetmacro?, il existe une limite de calcul, fixée à 16 383, très exactement $\frac{2^{30} - 1}{2^{16}}$. Du coup, si tu veux tracer un polygone de 17 000 côtés, c'est impossible. Et je n'aborde pas l'intérêt d'un tel tracé : autant utiliser un cercle dans ce cas !
Généralement, pour des cas raisonnables, il ne devrait pas y avoir de problème mais il est bon de connaître cette notion. \\
Dans le cas où une telle erreur apparaît, le compilateur devrait afficher l'erreur \og \verb?! Dimension too large.? \fg{}. \textcolor{Red}{\textbf{Mais il peut aussi arriver que cette limite apparaisse alors que les calculs ne dépassent pas la valeur interdite !}}
Par exemple, trace un polygone de 50 côtés avec mon code précédent et essaye les deux possibilités suivantes dans la boucle \verb?for? :
\begin{itemize}[label = \ding{213}]
\item \verb?{-- (90-\i/\poly*360:\R)}? : aucun problème,
\item \verb?{-- (90-\i*360/\poly:\R)}? : problème \dots{} alors que, d'un point de vue purement formel, le calcul est le même !
\end{itemize}
De ce que j'ai compris, il s'agit d'une erreur due à un dépassement de pile (\textit{stack overflow}) sous \TikZ{}. Pour l'éviter, il faut \textbf{toujours privilégier les divisions au début du calcul.}
\end{attention}
\section{Dessiner des figures mathématiques}
Je ne vais pas m'attarder sur cette section, juste donner deux pistes de recherche. Si tu as beaucoup de figures géométriques à dessiner, et surtout des figures mathématiques, avec beaucoup de sommets, des intersections, etc., tu peux :
\begin{itemize}[label = \ding{213}]
\item utiliser le logiciel gratuit \verb?GeoGebra? (\url{https://www.geogebra.org/}) et exporter les figures en code \TikZ{} ;
\item utiliser le package \verb?tkz-euclide?, qui possède une documentation bien fournie et beaucoup de commandes intéressantes. \\
\end{itemize}
Et voici un premier exemple de mise en bouche pour tracer une fonction :
\begin{codetikz}{Une fonction bien connue et son inverse}
\begin{tikzpicture}[samples = 130]
\draw[->] (-2,0) -- (2,0) node[right] {$x$};
\draw[->] (0,-2) -- (0,2) node[above, text = cyan] {$\sin x$};
\draw (-1.57,1mm) -- (-1.57,-1mm) node[below] {\footnotesize $-\frac{\pi}{2}\phantom{-}$};
\draw (1.57,1mm) -- (1.57,-1mm) node[below] {\footnotesize $\frac{\pi}{2}$};
\draw (1mm,-1) -- (-1mm,-1) node[left] {$-1\strut$};
\draw (1mm,1) -- (-1mm,1) node[left] {$1\strut$};
\node[below right] at (0,0) {$0$};
\draw[thick, color = cyan, domain = -1.57:1.57] plot ({\x},{sin(deg(\x))}); % deg pour conversion
\end{tikzpicture}
\hfill
\begin{tikzpicture}[samples = 130]
\draw[->] (-2,0) -- (2,0) node[right] {$x$};
\draw[->] (0,-2) -- (0,2) node[above, text = red] {$\arcsin x$};
\draw (-1,1mm) -- (-1,-1mm) node[below] {$-1\phantom{-}$};
\draw (1,1mm) -- (1,-1mm) node[below] {$1$};
\draw (1mm,-1.57) -- (-1mm,-1.57) node[left] {\footnotesize $-\frac{\pi}{2}\strut$};
\draw (1mm,1.57) -- (-1mm,1.57) node[left] {\footnotesize $\frac{\pi}{2}\strut$};
\node[below right] at (0,0) {$0$};
\draw[thick, dashed, color = red, domain = -1:1] plot ({\x},{rad(asin(\x))}); % rad pour conversion
\end{tikzpicture}
\end{codetikz}
Comme tu peux le constater, je trace le repère et les points remarquables (traits sur le repère) à la main. Puis, j'utilise \verb?plot ({\x},{f(\x)})? pour le tracé de la fonction.
Il existe sûrement d'autres syntaxes pour tracer des courbes polaires ou avec plusieurs variables. Je te laisse te documenter à ce sujet si tu en as besoin. Le package \verb?pgfplots? peut proposer des éléments de solution. \\
Bien, maintenant que nous connaissons le fonctionnement de \TikZ{} et l'avons un peu manipulé, voyons maintenant des méthodes élégantes pour gérer facilement la forme de tes dessins, et donc toutes les options disponibles.
\section{Gestion des styles}
\begin{attention}{Chargement du package \verb?xcolor?}
Avant de commencer à parler de style, je dois aborder un cas assez délicat : l'importation du package \verb?xcolor?, et encore plus de ses options, dont \verb?dvipsnames? pour ma part. Qui dit style pense alors à couleur : \verb?xcolor? est alors indispensable. Mais il peut se produire une erreur à la compilation.
Il faut déjà savoir qu'il faut toujours charger \verb?xcolor? avant \verb?tikz?. Mais, dans certains cas (utilisation d'autres packages principalement), il peut arriver qu'il y ait un conflit et que l'erreur \verb?Option clash for package xcolor? surgisse. \\
Il existe alors 2 solutions : \begin{itemize}[label = \ding{213}]
\item identifier le package qui pose problème et charger \verb?xcolor? avant. Dans mon cas, je me suis rendu compte que le package \verb?tcolorbox? était la source des erreurs : j'appelle donc \verb?xcolor? \textbf{avant} ;
\item appeler la commande suivante \textbf{avant} l'appel de la classe \verb?documentclass? : \begin{center} \verb?\PassOptionsToPackage{dvipsnames}{xcolor}? \end{center}
\end{itemize}
Maintenant que tu es au courant de cette astuce, je ferme la parenthèse et je passe aux styles.
\end{attention}
Imaginons un instant que nous avons plein de traits, de rectangles et de cercles à tracer. Bref, pleins d'éléments qui requiert d'utiliser beaucoup de \verb?\draw?. Nous voulons aussi que tous ces éléments aient le même format (couleur, épaisseur de trait, etc.), pour homogénéiser le rendu. \\
Il est possible de définir un style global pour un dessin, lors de l'appel de l'environnement \verb?tikzpicture?. Au lieu d'écrire \verb?\draw[<options>]? à chaque fois et de devoir tout changer manuellement, il est possible d'ajouter des options à l'environnement de la manière suivante : \begin{center} \verb?\begin{tikzpicture}[<options>]? \end{center}
Si nous avons besoin de définir plusieurs styles distincts, c'est possible de regrouper toutes les options dans un nom de style pour pouvoir les appeler directement. Il faut alors utiliser la syntaxe suivante : \begin{center} \verb?<nom-style>/.style = {<options>}? \end{center}
Tu peux déclarer ton style soit lors de l'appel de l'environnement \verb?tikzpicture?, soit avec la commande \verb?\tikzset{<def-style>}?, avant d'appeler le style en question dans les options : \verb?\draw[<nom-style>]?. \\
Enfin, il est toujours possible de procéder à des changements ponctuels dans les options d'un \verb?\draw?. \textbf{Placés \emph{après} un style,} ils prédomineront à coup sûr (lecture de gauche à droite des options et la dernière option lue est appliquée).
D'une certaine manière, nous pouvons voir \verb?<nom-style>? comme une variable qui contient du texte que \LaTeX{} et \TikZ{} se chargent de copier-coller à chaque appel du style. \\
Un petit exemple pour bien comprendre, comme d'habitude :
\begin{codetikz}{Les styles sous \TikZ{}}
% Paramètre défini globalement
\def\R{1.5}
% Style global
\begin{tikzpicture}[thick, red, dashed]
\draw circle (\R);
\draw (\R,0) --++ (-2*\R,0);
\draw (0,\R) --++ (0,-2*\R);
\end{tikzpicture}
\hfill
% Styles locaux
\begin{tikzpicture}[thick, red, dashed]
\draw[solid, thin] circle (\R);
% solid = trait plein
\draw (\R,0) --++ (-2*\R,0);
% Bien mettre un * pour le calcul
% Ne pas confondre avec les longueurs : 0.5\linewidth licite
\draw[cyan, ultra thick] (0,\R) --++ (0,-2*\R);
\end{tikzpicture}
\hfill
% Style groupé
\begin{tikzpicture}[thick, red, dashed]
\tikzset{pointille/.style = {purple, line width = 4pt, line cap = round, dash pattern = on 0pt off 2.5\pgflinewidth}}
% Style dotted pas très "dot" --> utilisation de line cap & dash pattern
\draw circle (\R);
\draw[pointille] (\R,0) --++ (-2*\R,0);
% Changement d'un style déjà défini
\draw[pointille, orange] (0,\R) --++ (0,-2*\R);
\end{tikzpicture}
\end{codetikz}
Bien évidemment, ici, le code est très simple et cette notion devient intéressante quand tu as beaucoup de \verb?\draw?, ou quand tu te rends compte que tu fais beaucoup de changements dans les options. Il devient alors plus intéressant de les automatiser avec des styles.
\begin{attention}{Appel de \texttt{\textbackslash}\verb?tikzset?}
Dans l'exemple fourni, le style \verb?pointille? est défini à l'intérieur de l'environnement \verb?tikzpicture?. Par conséquent, il n'est utilisable que pour cet environnement. En l'état, impossible de l'appeler dans un autre environnement \verb?tikzpicture?. \\
Toutefois, \verb?\tikzset? est utilisable à n'importe quel endroit de ton code \LaTeX{}. Tu peux donc l'appeler en-dehors de l'environnement \verb?tikzpicture?. Il sera alors disponible pour toutes les figures à venir.
Tu peux donc même définir tes styles dans le préambule. C'est plus facile à gérer (regroupement de toutes les commandes dans un même endroit au sein de ton code) et tu peux t'en servir à volonté par la suite !
\end{attention}
Maintenant que la gestion de la mise en forme avec les styles est bien définie et que nous savons tracer quelques figures élémentaires, pimentons un peu les possibilités. Ajoutons du texte !
\section{Insérer du texte}
Il n'y a qu'une seule façon d'écrire dans un dessin réalisé sous \TikZ{} : utiliser les \verb?node?. Très exactement, les \verb?node? permettent de placer à peu près tout et n'importe quoi à l'endroit souhaité dans le dessin, en particulier du texte. \\
Un \verb?node? s'appelle par une commande, selon la syntaxe suivante :
\begin{code}{}
\node[<options>] (<nom>) at (<coord>) {<texte>};
\end{code}
Il existe de multiples possibilités en ce qui concerne les options d'un \verb?node? (\verb?<options>?). Celles que j'utilise fréquemment sont les suivantes et sont rappelées en \autoref{annexes-tikz-node} (annexes p. \pageref{annexes-tikz-node}) :
\begin{itemize}[label = \ding{213}]
\item \verb?circle? (\verb?rectangle? par défaut) : pour avoir un cercle comme cadre au lieu du rectangle. Différents formats sont disponibles et sont explicités dans les exemples un peu après ;
\item \verb?draw = <color>? (\verb?black? par défaut) : pour afficher le cadre du \verb?node? et définir sa couleur ;
\item \verb?fill = <color>? : la couleur de remplissage du cadre ;
\item \verb?text = <color>? : la couleur du texte ;
\item \verb?font = <mise-en-forme>? : pour mettre en forme le texte (\verb?\bfseries?, \verb?\itshape?, \verb?\small?, etc.) ;
\item \verb?align = <position>?, avec \verb?<position>? qui peut prendre les valeurs \verb?left?, \verb?center? ou \verb?right? : pour aligner horizontalement le texte à l'intérieur du \verb?node? ;
\item \verb?inner sep = <taille>? : espacement entre le texte et le bord du \verb?node? ;
\item \verb?outer sep = <taille>? : espacement entre le bord du \verb?node? et les autres éléments ;
\item \verb?text width = <taille>? : largeur de la boîte (invisible) dans laquelle est placée le texte. Si \verb?text width? est inférieur à \verb?minimum width?, la boîte en question est centrée.
Toutefois, le texte à l'intérieur peut continuer à être excentré si \verb?text width? est supérieur à la taille minimale du texte. Dans ce cas, utiliser l'option \verb?align? pour centrer à ta convenance ;
\item \verb?minimum width = <taille>? : largeur minimale du cadre ;
\item \verb?minimum height = <taille>? : hauteur minimale du cadre ;
\item \verb?<position>? (\verb?above?, \verb?below?, \verb?left? ou \verb?right?) : pour positionner le \verb?node? par rapport à \verb?<coord>? ;
\item \verb?rotate = <angle>? : pour faire pivoter le \verb?node?. \\
\end{itemize}
Un premier exemple d'application peut prendre la forme suivante :
\begin{codetikz}{Utilisation des \verb?node?}
\begin{center}
\begin{tikzpicture}
% Cas simple
\draw (0,0) -- (1,0);
\node at (0.5,0.5) {Texte};
% Affichage de la bordure rectangulaire du node
\node[draw] at (0.5,2) {some text};
% Changement du cadre avec circle (rectangle par défaut)
\node[draw, circle, align = left] at (4,1.5) {Texte sur 2 lignes \\ Retour ligne manuel};
% Cas plus complet
\node[draw = Green, line width = 8pt, fill = red!30, font = \scshape, text = gray!75!black, thick, minimum width = 4.5cm, text width = 4cm, minimum height = 2cm, align = center, rotate = 90] at (8,1.5) {Texte centré \\ sur 2 lignes};
\end{tikzpicture}
\end{center}
\end{codetikz}
\begin{attention}{Saut de ligne dans un \verb?node?}
Le saut de ligne manuel avec \verb?\\? est licite et fonctionnel dans un \verb?node? si et seulement si l'option \verb?align = <position>? est utilisée.
Sans cette option, \TikZ{} écrit le texte seul et n'interprète pas le saut de ligne. Avec cette option, il doit placer ton texte dans une \verb?parbox? bien paramétrée avec le centrage indiqué, ce qui rend le saut de ligne possible.
Mais c'est mon hypothèse personnelle : il faudrait aller lire la documentation voire le code source pour s'en assurer.
\end{attention}
Comme indiqué, les \verb?node? peuvent prendre différentes formes, dont voici une liste non exhaustive : \begin{itemize}[label = \ding{118}]
\item formes simples : \verb?rectangle?, \verb?circle?, \verb?ellipse?, \verb?diamond?, \verb?circle split?, \verb?forbidden sign?, \verb?cross out?, \verb?strike out? ;
\item formes plus ``complexes'' (options supplémentaires) : \begin{itemize}[label = \ding{213}]
\item \verb?regular polygon? \& \verb?regular polygon sides = 5?,
\item \verb?star?, \verb?star points = 7? \& \verb?star point ratio = 0.8?. \\
\end{itemize}
\end{itemize}
Certaines formes sont disponibles grâce à différentes bibliothèques \TikZ{}, à charger après l'appel du package. Pour avoir un aperçu des différents formats disponibles, c'est par ici avec un exemple minimal :
\begin{codetikz}{Les différents formats de \verb?node?}
% Ajout au PREAMBULE
%\usepackage{tikz}
%\usetikzlibrary{shapes.geometric, shapes.misc, shapes.multipart, shapes.symbols}
\begin{tikzpicture}
% Affichage sous forme d'un tableau (syntaxe identique)
\matrix[nodes = {draw, ultra thick, fill = blue!20}, row sep = 3mm, column sep = 4mm] {%
\node[draw = none, fill = none] {Plain node}; & \node[rectangle] {Rectangle}; & \node[circle] {Circle}; \\
\node[ellipse] {Ellipse}; & \node[circle split] {Circle \nodepart{lower} split}; & \node[forbidden sign, text width = 4em, text centered] {Forbidden sign}; \\
\node[diamond] {Diamond}; & \node[cross out] {Cross out}; & \node[strike out] {Strike out}; \\
};
\end{tikzpicture}
\begin{tikzpicture}[note/.style = {draw = none, fill = none, right}]
\matrix[nodes = {draw, ultra thick, fill = blue!20}, row sep = 3mm, column sep = 4mm] {%
\node[regular polygon, regular polygon sides = 5] {$n = 5$}; & \node[regular polygon, regular polygon sides = 7] {$n=7$}; & \node[regular polygon, regular polygon sides = 9] {$n=9$}; & \node[note]{Regular polygon}; \\
\node[star, star points = 4] {$p = 4$}; & \node[star, star points = 7, star point ratio = 0.8] {$p=7$}; & \node[star, star points = 9] {$p = 9$}; & \node[note]{Star}; \\
};
\end{tikzpicture}
\end{codetikz}
Mais tu peux tout faire avec des \verb?node?. Par exemple, tu peux les placer à l'intérieur d'un chemin dessiné par un \verb?\draw? pour ajouter de l'information (texte ou symbole).
L'intérêt ? Pendant que tu traces ton dessin, tu associes l'information à la coordonnée, au lieu d'ajouter le texte manuellement par la suite. C'est très pratique si tu modifies ton dessin ou si les coordonnées sont difficiles à déterminer.
En revanche, ton code est moins lisible à relire\dots{} Reprenons un ancien exemple, qui devrait te sembler plus clair désormais :
\begin{codetikz}{Ajouter de l'information sur un tracé avec des \verb?node?}
\begin{center}
\begin{tikzpicture}[cercle/.style = {circle, inner sep = 2pt}]
\draw[gray, dotted] (0,-1) grid (3,1);
% Les node en cascade, c'est le nec plus ultra !
\draw (0,0) node[cercle, fill = red] {} node[left] {Début} --++ (1,1) --++ (2,0) --++ (0,-1) node[cercle, fill = blue] {} node[right] {Fin};
\draw (0,0) -- (1,-1) node[right, align = left] {Nouvelle \\ branche};
\end{tikzpicture}
\end{center}
\end{codetikz}
Pour rappel, le saut de ligne manuel avec \verb?\\? est licite et fonctionnel dans un \verb?node? si et seulement si l'option \verb?align = <position>? est utilisée.
Les options comme \verb?above? ou \verb?below? permettent d'ajuster la position du \verb?node? par rapport à la coordonnée à laquelle il se réfère. Des combinaisons sont possibles, comme \verb?above left?. Toutefois, il faut respecter un certain ordre : \verb?left above? ne fonctionne pas par exemple.\footnote{Je n'ai pas d'astuce pour s'en souvenir. Je le sais et je fais attention à bien lire les erreurs de compilation annoncées pour vite corriger le tir.} \\
Bon, je crois avoir à peu près fait le tour en ce qui concerne la base pour les \verb?node?. Voyons une dernière application, plus poussée : la création de graphes et de diagrammes.
\section{Création de graphes et de diagrammes}
\subsection*{Les points d'ancrage}
Sous \TikZ{}, un \verb?node? est constitué de points d'ancrage, répartis de la manière suivante :
\begin{figure}[H]
\centering
\begin{tikzpicture}
\node[draw = gray!50, line width = 8pt, text = RedOrange, font = \LARGE, minimum width = 0.5\linewidth, minimum height = 3cm, text width = 0.25\linewidth, align = center] (master) at (0,0) {node \verb?N?};
\tikzset{every node/.style = {font = \ttfamily}}
% Les points d'ancrage les plus intuitifs
\foreach \anchor in {north, north east, east, south east, south, south west, west, north west} {\node at (master.\anchor) {$\times$};}
\node[above = 5pt] at (master.north) {\texttt{N.north}};
\node[above right = 5pt] at (master.north east) {\texttt{N.north east}};
\node[right = 5pt] at (master.east) {\texttt{N.east}};
\node[below right = 5pt] at (master.south east) {\texttt{N.south east}};
\node[below = 5pt] at (master.south) {\texttt{N.south}};
\node[below left = 5pt] at (master.south west) {\texttt{N.south west}};
\node[left = 5pt] at (master.west) {\texttt{N.west}};
\node[above left = 5pt] at (master.north west) {\texttt{N.north west}};
% Les autres points d'ancrage
\node[text = cyan] at (master.13) {$\times$};
\node[text = Green] at (master.base) {$\times$};
\node[text = Green] at (master.text) {$\times$};
\node[text = Orchid] at (master.center) {$\times$};
\node[right = 5pt, text = cyan] at (master.13) {N.13 (angle)};
\node[below = 5pt, text = Green] at (master.base) {N.base};
\node[below left, yshift = -5pt, text = Green] at (master.text) {N.text};
\node[above = 5pt, text = Orchid] at (master.center) {N.center = N};
\end{tikzpicture}
\caption{Vue d'un \texttt{node} et de ses points d'ancrage}
\end{figure}
J'ai pris le cas traditionnel d'un \verb?node? rectangulaire mais les points d'ancrage sont parfaitement définis pour toutes les autres formes, si besoin (cercle, étoile, polygone régulier, etc.). \\
Voyons maintenant comment utiliser cette notion pour placer deux \verb?node? sous forme de boîte l'un par rapport à l'autre. Nous allons utiliser judicieusement les styles déjà évoqués et les points d'ancrage.
Cette méthode permet d'avoir à placer un seul \verb?node? (référence) et tout peut se faire relativement à ce dernier, ou relativement aux nouveaux \verb?node?.
Une nouvelle option est alors adaptée à la situation : \verb?anchor = <ancre>?. De cette manière, tu peux spécifier le point d'ancrage sur lequel le \verb?node? va se fixer. Le point d'ancrage utilisé par défaut est \verb?center?.
\begin{conseil}{Style global aux \verb?node?}
Si nous avons déjà vu la syntaxe pour créer un style sous \TikZ{} et les configurations disponibles (style global ou local), il est possible d'indiquer directement un style à tous les \verb?node?, grâce à la syntaxe suivante :
\begin{code}{}
\begin{tikzpicture}[every node/.style = {<options>}]
% Dessiner !
\end{tikzpicture}
\end{code}
Mais cette option est à utiliser judicieusement : c'est pratique si tous tes \verb?node? sont des boîtes. C'est plus gênant à corriger si tu ajoutes en milieu de chemin un \verb?node? simple, pour écrire un commentaire par exemple.
\end{conseil}
Après la théorie, un peu de pratique avec un premier code d'initiation :
\begin{codetikz}{Initiation aux points d'ancrage}
\begin{center}
\begin{tikzpicture}[every node/.style = {draw = orange, very thick, minimum width = 2cm, minimum height = 1cm}]
% Node "master" (référence)
\node (master) at (0,0) {Boîte maître};
% Node créé relativement à "master"
\node[anchor = west, xshift = 2cm] (boiteA) at (master.east) {Boîte A};
% Positionnement de l'ancrage ouest de boiteA sur l'ancrage est de "master"
% Décalage horizontal manuel avec xshift
\draw (master) -- (boiteA);
% TikZ trace le trait le plus simple pour relier 2 node
% Troisième node
% Décalage vertical manuel avec yshift
\node[draw = Green, fill = gray!50, minimum width = 2cm, yshift = -2cm] (boiteB) at (boiteA.south west) {Boîte B};
% Tracé d'un trait "|-|" automatisé
% Création d'un node milieu
\path (master.south) -- (boiteB.north) coordinate [midway] (middle);
\draw (master.south) |- (middle) -| (boiteB.north);
\end{tikzpicture}
\end{center}
\end{codetikz}
Bon, d'accord, je triche un peu avec les décalages \verb?xshift? et \verb?yshift?. Ce n'est clairement pas une solution optimale s'il faut tout décaler manuellement à chaque fois.
Mais le principe de base est là ! Voyons maintenant comment mieux faire avec des cas concrets.
\subsection*{Organigramme manuel}
Nous allons continuer sur notre lancée avec un premier organigramme dessiné manuellement. Après tout, il peut des fois être plus rapide de faire un premier dessin manuellement que de chercher à tout optimiser et automatiser dès le départ.
Le principe est très similaire à celui montré dans le code d'initiation précédent : \begin{enumerate}
\item Création de l'environnement \verb?tikzpicture? et définition d'un style global pour tous les \verb?node? pour garantir l'homogénéité du résultat.
\item Création du \verb?node? de référence, \og \verb?master? \fg{}. Comme aucune coordonnée n'est spécifiée, \verb?master.center? se situe en \verb?(0,0)?.
\item Positionnement d'autres \verb?node? (boîtes en-têtes) puis utilisation des points d'ancrage pour placer des \verb?node? en dessous des précédents (boîtes descriptives).
\item Relier les boîtes pour donner un sens à l'organigramme (\verb?\draw?) et ajuster la taille si besoin avec \verb?\resizebox? (package \verb?graphicx?). \\
\end{enumerate}
Concrètement, le code ressemble à :
\begin{codetikz}{Organigramme manuel}
% Ajout au PREAMBULE
%\usepackage{graphicx, tikz}
\resizebox{\linewidth}{!}{
\begin{tikzpicture}[
every node/.style = {draw = black, fill = violet!70, line width = 2pt, text width = 3cm, minimum width = 3.5cm, minimum height = 1cm, text = white, align = center},
entete/.style = {font = \large},
descr/.style = {minimum height = 3cm}]
% Node de référence
\node[font = \Large] (master) {Manager};
% Autres nodes
\node[entete] (boiteA) at (-6,-3) {\'Equipe A};
\node[descr, anchor = north] at (boiteA.south) {Commercial \\ ~ \\ Vente};
\node[entete] (boiteB) at (-2,-3) {\'Equipe B};
\node[descr, anchor = north] at (boiteB.south) {PHP \\ ~ \\ JavaScript};
\node[entete] (boiteC) at (2,-3) {\'Equipe C};
\node[descr, anchor = north] at (boiteC.south) {Support \\ ~ \\ Supervision};
\node[entete] (boiteD) at (6,-3) {\'Equipe D};
\node[descr, anchor = north] at (boiteD.south) {Analyse \& KPI \\ ~ \\ Management};
% Tracé automatisé
\foreach \point in {A, ..., D} {\draw[ultra thick] (master.south) --++ (0,-1cm) -| (boite\point);}
% -| <==> départ horizontal, arrivée verticale
\end{tikzpicture}
}
\end{codetikz}
Bon, jusque là, rien de nouveau, hormis la commande \verb?\resizebox? très pratique pour faire tenir les diagrammes quand ils ne rentrent pas dans ton document. Pour t'en servir, c'est très simple. La syntaxe générale est la suivante :
\begin{code}{}
\usepackage{graphicx}
\resizebox{<largeur>}{<hauteur>}{<élément>}
% Option "!" : permet de conserver les proportions
Utilisation la plus courante :
\resizebox{\linewidth}{!}{<élément>}
\end{code}
Si tu as besoin de plus de précisions, je te renvoie à la documentation du package \verb?graphicx?, disponible sur \url{https://ctan.org/pkg/graphicx}. \\
Voyons désormais un nouveau cas de diagramme. J'espère que tu aimes la Nature.
\subsection*{Utilisation d'un arbre}
Un arbre peut se révéler satisfaisant pour représenter un organigramme, surtout s'il est similaire au premier cas présenté. \TikZ{} offre la possibilité de construire automatiquement l'arbre en question, sans avoir à te soucier du positionnement. \textbf{Au préalable,} il faut penser à charger la bibliothèque \TikZ{} nommée \verb?trees?.
Le principe de création d'un arbre est très similaire à ce que nous avons vu jusqu'à présent : \begin{itemize}[label = \ding{118}]
\item création d'un \verb?node? de référence (ou la graine de l'arbre). Il s'agit alors du niveau 0 (\verb?level 0?) ;
\item création des ramifications (\verb?child?) avec la syntaxe suivante :
\begin{code}{}
child { node[<options>] {<texte>} }
\end{code}
Pour créer de nouvelles ramifications, il faut jouer sur l'encapsulation d'un nouveau \verb?child? avant la fermeture de l'accolade finale. Il est alors fortement recommandé d'indenter son code dans cette situation : la relecture n'en sera que plus simple.
La ramification -- ou niveau -- $i$ peut alors être appelée avec la syntaxe \verb?level i?. C'est surtout utile pour définir un style propre à chaque niveau, comme nous le verrons dans l'exemple qui va suivre ;
\item il existe des options propres aux arbres. Par exemple, \verb?level distance? permet de définir l'espace entre chaque niveau. \verb?sibling distance? fait de même, mais pour les éléments d'un même niveau.
\verb?edge from parent path? permet de définir la manière dont sont reliés les éléments. Des n\oe{}uds génériques (gérés automatiquement par \TikZ{}, pour chaque niveau et élément) sont alors accessibles par les noms \verb?\tikzparentnode? et \verb?\tikzchildnode?. \\
\end{itemize}
Voyons maintenant sur un cas concret ce que nous pouvons réaliser :
\begin{codetikz}{Création d'un arbre avec \verb?trees?}
% Ajout au PREAMBULE
%\usepackage{tikz}
%\usetikzlibrary{trees}
\resizebox{\linewidth}{!}{
\begin{tikzpicture}[every node/.style = {rounded corners, draw, top color = white, bottom color = blue!20, align = center}, level distance = 50pt, level 1/.style = {sibling distance = 17em}, level 2/.style = {sibling distance = 8em}, edge from parent/.style = {draw, edge from parent path = {(\tikzparentnode.south) --+ (0,-10pt) -| (\tikzchildnode)}}]
\node {NOM \\ Chef}
child { node {Sous-chef A}
child { node {Esclave Aa}}
child { node {Esclave Ab}}
}
child { node {Sous-chef B}
child { node {Esclave Ba}
child { node {Stagiaire Ba1}}
child { node {Stagiaire Ba2}}
child { node {Stagiaire Ba3}}
}
child { node {Esclave Bb}}
};
\end{tikzpicture}
}
\end{codetikz}
\begin{attention}{Saut de ligne interdit !}
Pour la création d'arbres, il est strictement interdit de sauter des lignes pour aérer le code, sous peine d'avoir une erreur de compilation (code mal interprété).
C'est pourquoi je recommande dans ce cas de figure d'indenter le code, avec un décalage pour chaque niveau. C'est ce que je fais dans mes exemples.
\end{attention}
Avec un peu de ruse lors de la configuration de \verb?edge from parent path?, un style judicieusement configuré avec l'option \verb?grow? (propre à la bibliothèque \verb?trees?), il est possible de relier différemment les éléments :
\begin{codetikz}{Une autre possibilité d'arbre}
% Ajout au PREAMBULE
%\usepackage{tikz}
%\usetikzlibrary{trees}
\begin{center}
\begin{tikzpicture}[man/.style = {draw, fill = blue!20}, woman/.style = {rounded corners = .8ex, draw, fill = red!20}, grandchild/.style = {grow = down, xshift = 1em, anchor = west, edge from parent path = {(\tikzparentnode.south) |- (\tikzchildnode.west)}}, first/.style = {level distance = 6ex}, second/.style = {level distance = 12ex}, third/.style = {level distance = 18ex}, level 1/.style = {sibling distance = 5em}]
% Parents
\coordinate
child[grow = left] {node[man, anchor = east] {Jim}}
child[grow = right] {node[woman, anchor = west] {Jane}}
child[grow = down, level distance = 0ex][edge from parent fork down]
% Enfants & petits-enfants
child{node[man] {Alfred}
child[grandchild, first] {node[man] {Joe}}
child[grandchild, second] {node[woman] {Heather}}
child[grandchild, third] {node[woman] {Barbara}}
}
child{node[woman] {Berta}
child[grandchild, first] {node[man] {Howard}}
}
child {node[man] {Charles}}
child {node[woman] {Doris}
child[grandchild, first] {node[man] {Nick}}
child[grandchild, second] {node[woman] {Liz}}
};
\end{tikzpicture}
\end{center}
\end{codetikz}
Voilà, c'est tout ce que je peux présenter concernant les arbres à l'heure actuelle. Heureusement, j'ai gardé le meilleur pour la fin, avec une solution un peu plus automatisée. Mais un interlude est nécessaire avant d'en parler.
\subsection*{Utiliser des flèches}
Les diagrammes que j'ai présentés jusqu'à présent peuvent convenir en l'état. Cependant, nous allons vite être limités pour transmettre plus d'informations si nous n'avons pas de flèches ! \\
Sous \TikZ{}, une flèche n'est ni plus ni moins qu'un trait (dessiné par \verb?\draw?) auquel des options supplémentaires sont précisées pour enrichir son ou ses extrémités, en l'occurrence avec des flèches : \begin{itemize}[label = \ding{118}]
\item \verb?->? : pour avoir une pointe de flèche à la fin du trait ;
\item \verb?<-? : pour avoir une pointe de flèche au début du trait ;
\item \verb?<->? : pour avoir une pointe de flèche à chaque extrémité ;
\item \verb?>-<? ou \verb?->>? ou \verb?>>>-? : autres combinaisons possibles et suffisamment explicites quand tu as compris le principe de fonctionnement ;
\item \verb?> = <fleche>? : pour spécifier une autre forme de flèche que celle par défaut. Les formes les plus classiques sont \verb?Stealth? et \verb?Straight Barb?.
Pour cette dernière, il faut charger la bibliothèque \TikZ{} \verb?arrows.meta?. Et si tu veux d'autres formes, cf. la documentation officielle de \TikZ{}\footnote{Disponible sur \url{https://www.ctan.org/pkg/pgf}.} ;
\item et bien d'autres options, pour agrandir la taille de la flèche, colorer la flèche d'une autre couleur que celle du trait, etc. Je renvoie, encore une fois, à la documentation officielle de \TikZ{} à ce sujet. \\
\end{itemize}
Un petit exemple d'application pour digérer tous ces éléments :
\begin{codetikz}{Flèches et cas pratiques}
\begin{center}
\begin{tikzpicture}
\draw (0,0) -- (0,2);
\draw[->, very thick] (2,0) -- (2,2);
\draw[<-, ultra thick] (4,0) -- (4,2);
\draw[>->, line width = 3pt] (6,0) -- (6,2);
\draw[<<-<, > = Stealth, line width = 5pt] (8,0) -- (8,2);
\end{tikzpicture}
\end{center}
\end{codetikz}
Bien, finissons maintenant avec un dernier diagramme.
\subsection*{Un beau diagramme ?}
Le principe de base reste inchangé : utilisation d'un \verb?node? de référence, positionnement des autres \verb?node? par rapport à la référence ou aux nouveaux \verb?node?, utilisation judicieuse des styles pour décorer.
Si le positionnement standard est intéressant, les possibilités deviennent plus intéressantes avec la bibliothèque \verb?positioning?. Selon moi, la meilleure façon de s'en servir est la suivante : \begin{enumerate}
\item L'option \verb?node distance = <ecart>? permet de définir l'écart entre chaque \verb?node? (localement sur un \verb?node? ou globalement lors de l'appel de l'environnement \verb?tikzpicture?).
\item Création du \verb?node? de référence, \verb?master?.
\item Positionnement d'un nouveau \verb?node? avec l'option : \verb?below = of master?. Résultat : celui-ci se retrouve sous \verb?master?, avec une séparation de taille \verb?<ecart>?. \\
\end{enumerate}
De manière plus générale, les 4 choix de positionnement -- \verb?above?, \verb?below?, \verb?left? et \verb?right?, qui peuvent être combinés, peuvent faire référence à un \verb?node? (ou un point d'ancrage spécifique) selon la syntaxe suivante :
\begin{code}{}
<position> = of <node>
\end{code}
Et c'est tout ! Maintenant, tu es libre de faire ce que tu veux, d'automatiser toutes les distances avec des longueurs \LaTeX{}. C'est ce que je fais en tout cas. Et je te propose ma petite \textit{template} personnelle pour faire des diagrammes :
\begin{coderesult}{\textit{Template} pour faire un diagramme}
\documentclass[a4paper, 12pt]{report}
% PDFLaTeX
\usepackage{lmodern}
\usepackage[french]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{enumitem, pifont}
\usepackage{pdflscape}
\usepackage[dvipsnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning}
\begin{document}
\everymath{\displaystyle}
\pagestyle{empty}
% Diagramme - Paramétrage
\definecolor{newblue}{RGB}{68,114,196}
\newlength{\nodesep}
\addtolength{\nodesep}{2.5cm}
\newlength{\blockwidth}
\addtolength{\blockwidth}{3.8cm}
\newlength{\blockheight}
\addtolength{\blockheight}{1.6cm}
% Style des blocs (diagramme)
\tikzset{
node distance = \nodesep,
block/.style = {draw = newblue, fill = newblue, text = white, rounded corners, minimum width = \blockwidth, minimum height = \blockheight, text width = \blockwidth - 2mm, align = center, font = \sffamily},
warning/.style = {block, draw = red, fill = red},
correct/.style = {block, draw = Green, fill = Green},
careful/.style = {block, draw = orange, fill = orange},
arrow/.style = {newblue, line width = 5pt, ->, > = Stealth},
comment/.style = {text width = \nodesep, align = center, font = \sffamily\itshape}
}
\begin{landscape}
\resizebox{\linewidth}{!}{
\begin{tikzpicture}
% Création des blocs
\node[block] (blocA) {Bloc A};
\node[careful, right = of blocA] (blocB) {Bloc B};
\node[block, below = of blocA] (blocC) {Bloc C};
\node[block, left = of blocC] (blocD) {Bloc D};
\node[careful, below = of blocD] (blocE) {Bloc E};
\node[careful, node distance = 2\nodesep + \blockwidth, right = of blocE] (blocF) {Bloc F};
\node[careful, below = of blocE] (blocG) {Bloc G};
\node[careful, right = of blocG] (blocH) {Bloc H};
\node[correct, right = of blocH] (blocI) {Bloc I};
% Liens entre les blocs et commentaires
\draw[arrow] (blocA) -- (blocB);
\draw[arrow] (blocA) -- (blocC);
\draw[arrow] (blocA) -| (blocD) node[left, text width = 0.8\blockwidth, align = left] at (blocD.west) {\textbf{Liste :} \begin{itemize}[label = \textcolor{newblue}{\ding{118}}, leftmargin = *]
\item puce a
\item puce b\dots{} \\ ~ \\
\end{itemize}
\textbf{\color{red!75!black}$\sf\times 2$ Tada !}};
\draw[arrow, orange] (blocB) -- (blocF);
\draw[arrow] (blocC) |- (blocF);
\draw[arrow] (blocD) -- node[comment, right] {Commentaire} (blocE);
\draw[arrow, orange] (blocE) -- (blocG);
% Création d'un node fictif (déviation)
\path (blocE) -- (blocG) coordinate [midway] (noeud fictif A);
\draw[arrow, orange] (blocF) node[comment, right] at (blocF.east) {Commentaire \\ Commentaire} |- (noeud fictif A) -| (blocG);
% Petite astuce (intersection / déviation)
% (blocA -| blocB) = coordonnée
\draw[arrow, orange] node[comment, left, align = right, text width = 1.2\blockwidth] at (blocG.west) {Commentaire \\ (détails) \\ Commentaire \\ Commentaire} (blocG) -- (blocH);
\draw[arrow, orange] (blocH) -- (blocI);
\end{tikzpicture}}
\end{landscape}
\end{document}
\end{coderesult}
\begin{conseil}{Mon petit conseil}
Avant de te lancer dans l'écriture de ton code \TikZ{}, pose ton diagramme sur le papier. Tu verras que tu gagneras du temps et que ce sera plus facile pour le transposer sous \LaTeX{}.
Tu peux aussi plus facilement l'améliorer sur papier en griffonnant au lieu de réécrire 13 fois le même code parce que tu changes constamment d'avis.
Enfin, j'ai mis des noms de \verb?node? en \textit{autoincrement} pour faciliter la compréhension de l'exemple. Il vaut mieux donner un nom explicite à ton \verb?node?. C'est plus facile si tu dois en ajouter un nouveau par la suite, que de devoir décaler tous tes noms de \verb?node?.
\end{conseil}
\section{Le mot de la fin}
Loin d'avoir tout expliqué sur \TikZ{}\footnote{Le guide officiel fait plus de 1~000 pages donc tu penses bien que je n'ai fait qu'effleurer le champ des possibles.}, les exemples que j'ai élaborés et mis à disposition au sein de ce guide donnent malgré tout beaucoup d'informations et constituent une première base solide.
Naturellement, je suis loin d'être exhaustif et je me suis efforcé d'aborder un large panel de notions que je connais. \`A toi désormais de faire des essais, d'améliorer ton code et de découvrir de nouvelles possibilités ! \\
\TikZ{} propose un grand nombre de bibliothèques, avec des fonctionnalités diverses et variées.
Elles sont détaillées à la partie V du guide officiel de \TikZ{}, ainsi que sur : \url{http://tex.stackexchange.com/questions/42611/list-of-available-tikz-libraries-with-a-short-introduction}.
Tu trouveras aussi un tableau bilan à ce sujet dans les annexes, \autoref{annexes-tikz-bibliotheques} p. \pageref{annexes-tikz-bibliotheques}. \\
Enfin, il existe aussi d'autres packages pour agrémenter les dessins sous \LaTeX{}. C'est par exemple le cas de \verb?pgfornament?, qui mérite le détour et fournit des ornements intéressants.
\begin{figure}[H]
\centering
\pgfornament[color = RedOrange, width = 0.6\linewidth]{60}
\caption{Un premier aperçu du package \texttt{pgfornament}}
\end{figure}
Pour finir, je me suis amusé à réaliser un petit fond d'écran pour mon ordinateur. Naturellement, il prône l'utilisation du \LaTeX{} et joue un peu sur la fibre patriotique. \\
Il est à disposition ci-après si tu veux réaliser une capture d'écran pour l'utiliser de ton côté. Tenter de le reproduire peut aussi constituer un bon entraînement dans ton apprentissage de \TikZ{}.
\clearpage
\includepdf[pages = -, fitpaper]{fond_TikZ}
|