NewDocumentCommand avec tkz-euclide

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.
zazou
Utilisateur confirmé
Utilisateur confirmé
Messages : 33
Inscription : mercredi 23 novembre 2022, 10:16
Statut actuel : Enseignant

NewDocumentCommand avec tkz-euclide

Message non lu par zazou »

Bonjour,

J'essaie de créer une macro pour étiqueter mes points correctement quand je trace un polygone avec tkz-euclide.

voici ce que j'essaie d'automatiser :

Code : Tout sélectionner

\documentclass{article}
\usepackage{tkz-euclide}

\begin{document}
\begin{tikzpicture}[scale=1]
\tkzDefPoints{0/0/S,2/3/O,-1/1/P}
\tkzDrawPolygon(S,O,P)
\tkzDefBarycentricPoint(S=1,O=1,P=1)\tkzGetPoint{Barycentre}
\foreach \i in {S,O,P}{
\tkzFindSlopeAngle(\i,Barycentre)
\tkzLabelPoint[anchor=\tkzAngleResult](\i){$\i$}}
\end{tikzpicture}
\end{document}
je cherche à créer une commande \nommepoints pour obtenir le même résultat en compilant ceci :

Code : Tout sélectionner

\documentclass{article}
\usepackage{tkz-euclide}

\begin{document}
\begin{tikzpicture}[scale=1]
\tkzDefPoints{0/0/S,2/3/O,-1/1/P}
\tkzDrawPolygon(S,O,P)
\nommepoints{S,O,P}
\end{tikzpicture}
\end{document}
à l'aide des packages xparse et xstring j'ai écrit

Code : Tout sélectionner

 \NewDocumentCommand\nommepoints{>{\SplitList{,}}m}  {  \StrGobbleRight{\ProcessList{#1}{ \egaleun }}{1}}
\newcommand\egaleun[1]{#1=1,}
qui me permet d'obtenir S=1,O=1,P=1 en écrivant \nommepoints{S,O,P} mais quand je demande \tkzDefBarycentricPoint(\nommepoints{S,O,P}) Latex me répond que \xparse function is not expandable

j'ai bien essayé de regarder \NewExpandableDocumentCommand mais ça ne fonctionne pas mieux : la doc dit qu'avec \NewExpandableDocumentCommand : • Argument processors (using >) are not available.

Je ne sais plus trop comment avancer... Quelqu'un a une idée ? Merci par avance.
Dernière modification par zazou le lundi 22 avril 2024, 16:12, modifié 1 fois.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2282
Inscription : samedi 29 décembre 2007, 00:58

Re: NewDocumentCommand avec tkz-euclide

Message non lu par projetmbc »

Bonjour.

Il faut toujours proposer un code compilable même s'il n'est pas totalement "fonctionnel".

Par avance merci.
zazou
Utilisateur confirmé
Utilisateur confirmé
Messages : 33
Inscription : mercredi 23 novembre 2022, 10:16
Statut actuel : Enseignant

Re: NewDocumentCommand avec tkz-euclide

Message non lu par zazou »

OK, j'ai édité mon message.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2282
Inscription : samedi 29 décembre 2007, 00:58

Re: NewDocumentCommand avec tkz-euclide

Message non lu par projetmbc »

Voilà une proposition via la machinerie L3 aka $\LaTeX3$. Si besoin, je peux commenter le code.

Afficher ou masquer le code

projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2282
Inscription : samedi 29 décembre 2007, 00:58

Re: NewDocumentCommand avec tkz-euclide

Message non lu par projetmbc »

Une méthode plus élégante.

Afficher ou masquer le code

zazou
Utilisateur confirmé
Utilisateur confirmé
Messages : 33
Inscription : mercredi 23 novembre 2022, 10:16
Statut actuel : Enseignant

Re: NewDocumentCommand avec tkz-euclide

Message non lu par zazou »

Bonjour, et merci pour tes deux propositions. Tu dis que la deuxième est plus élégante, je te crois sur parole, je ne comprends pas grand chose ni à l'une ni à l'autre ! C'est une syntaxe qui m'est totalement étrangère, mais je vais essayer d'y aller à l'intuition.

Si je comprends bien, \clist_new définit une liste à l'aide de l'argument de la commande, et \cs_new la commande à proprement parler. \tl_new définit une chaine de caractères, à l'aide de la liste définie plus tôt, et \tl_set et \tl_put_right y ajoutent les caractères manquants. par contre je ne comprends pas le \clist_map_inline.

Tout ceci fonctionne bien mieux que ce que j'avais ébauché car la chaîne de caractère \l_zazou_bary_spec_tl étant une chaîne de caractères, elle n'a pas besoin d'être développée pour être un argument valable pour \tkzDefBarycentricPoint, c'est ça ?

En tout cas, merci beaucoup !

Une petite remarque toutefois, il manque un \tkzGetPoint{Barycentre} juste après \tkzDefBarycentricPoint( \tl_use:N \l_zazou_bary_spec_tl ).
Ton code ne compile que parce qu'il utilise le barycentre défini dans l'exemple "à la main". Et j'ai sorti le \tkzDrawPolygon(#1) parce que je ne pense pas en avoir besoin tout le temps.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2282
Inscription : samedi 29 décembre 2007, 00:58

Re: NewDocumentCommand avec tkz-euclide

Message non lu par projetmbc »

Oui, c'est à peu près cela. Voici le 2nd code commenté.

Code : Tout sélectionner

\documentclass{article}

\usepackage{tkz-euclide}

\ExplSyntaxOn

\NewDocumentCommand\polygonom{ m }{  
  \zazou_polygonom:n { #1 }
}

% Création de deux variables.
%   1) Une liste de tokens initialement séparés par des virgules, 
%      soit une `clist` pour "coma separated list".
%   2) Une suite de tokens pour spécifier l'isobarycentre.
\clist_new:N \l_zazou_names_clist
\tl_new:N    \l_zazou_bary_spec_tl

\cs_new:Npn \zazou_polygonom:n #1 {
  \tkzDrawPolygon( #1 )

% Création de la liste de chaque groupe des tokens séparé par
% des virgules dans `#1`.
  \clist_set:Nn \l_zazou_names_clist 
                { #1 }

% On crée une suite de tokens spécifiant l'isobarycentre : 
% on "colle" les tokens stockés dans `\l_zazou_names_clist` 
% en les séparant avec des "=1,".
  \tl_set:Nn \l_zazou_bary_spec_tl 
             { \clist_use:Nn \l_zazou_names_clist { =1, } }

% On rajoute à droite un "=1" final.
  \tl_put_right:Nn \l_zazou_bary_spec_tl { =1 }
 
% On utilise nos tokens spécifiant l'isobarycentre. 
  \tkzDefBarycentricPoint( \tl_use:N \l_zazou_bary_spec_tl )
  \tkzGetPoint{Barycentre}

% On fait de la programmation fonctionnelle : on itère sur 
% la liste `\l_zazou_names_clist`, et pour chaque item, 
% accessible via ##1, on effectue ce que l'on souhaite.
  \clist_map_inline:Nn \l_zazou_names_clist {
    \tkzFindSlopeAngle( ##1, Barycentre )
    \tkzLabelPoint[anchor=\tkzAngleResult]( ##1 ){ $##1$ }
  }
}

\ExplSyntaxOff


\begin{document}

\section{À la main}

\begin{tikzpicture}[scale=1]
  \tkzDefPoints{0/0/S,2/3/O,-1/1/P}
  \tkzDrawPolygon(S,O,P)
  \tkzDefBarycentricPoint(S=1,O=1,P=1)
  \tkzGetPoint{Barycentre}
  \foreach \i in {S,O,P}{
    \tkzFindSlopeAngle(\i,Barycentre)
    \tkzLabelPoint[anchor=\tkzAngleResult](\i){$\i$}
  }
\end{tikzpicture}


\section{Semi-automatisé}

\begin{tikzpicture}[scale=1]
  \tkzDefPoints{0/0/S,2/3/O,-1/1/P}
  \polygonom{S,O,P}
\end{tikzpicture}


\section{Semi-automatisé bis}

\begin{tikzpicture}[scale=1]
  \tkzDefPoints{0/0/A,2/3/B,-1/3/C,-4/-3/D}
  \polygonom{A,B,C,D}
\end{tikzpicture}

\end{document}
zazou a écrit : mardi 23 avril 2024, 10:50 C'est une syntaxe qui m'est totalement étrangère, mais je vais essayer d'y aller à l'intuition.
C'est du $\LaTeX3$. Plus efficace en terme de codage à l'usage.
Altermundus
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 558
Inscription : lundi 28 mai 2007, 10:31
Statut actuel : Autre
Localisation : Paris

Re: NewDocumentCommand avec tkz-euclide

Message non lu par Altermundus »

Il existe une macro dans tkz-euclide qui peut faire cela, mais en la testant avec les exemples donnés, je découvre que je n'ai pas fait au plus simple.
Il va falloir que je la modifie. Cela dit je l'avais abandonnée car je trouvais dans certains cas, les résultats pas trop satisfaisants. Je vais revenir sur cette appréciation, car j'ai assez mal programmé ce code.
Pour obtenir des résultats semblables à \polygonom{A,B,C}, il est nécessaire de vider Label Style. J'ai introduit c e style dans la macro afin de conserver la couleur, la taille des labels, mais malheureusement la position est affectée par la position par défaut. De plus, j'ai sans doute compliqué inutilement la macro en permettant à l'utilisateur de choisir un point autre que l'isobarycentre avec l'option "center".

Le problème , sur une figure plus compliquée, c'est que les labels peuvent se placer sur d'autres objets, ou d'autres labels.

La macro est

Code : Tout sélectionner

\begin{tikzpicture}[scale=.8]
  \tkzDefPoints{2/1/A,5/3/B,0/6/C}
  \tkzDefBarycentricPoint(A=1,B=1,C=1)
  \tkzGetPoint{G}
  \tkzDrawPolygon(A,B,C)
  \tkzDrawLines[add=0 and 1,red](A,G B,G C,G)
  \tkzDrawPoints(A,B,C)
  \tikzset{Label Style/.style = {}}
  \tkzLabelPoint[above right](G){$G$}
  \tkzAutoLabelPoints[center=G,dist=0.1](A,B,C)
   \polygonom{A,B,C}
\end{tikzpicture}