9

My English is not good enough so I beg you to excuse me if the question is long

The next code is not very interesting but it may illustrate correctly my problem.

I have a lot of macros and I need actually a lot of temporary nodes. I tried until now to use different names,but these names become too numerous. Now I try to use the same names for the temporary nodes but I get some side effects.

A] Example 1 The next code shows that nodes are not defined locally to the environment "tikzpicture". The problem is that the nodes continue to exist between the tikzpicture environments. I suppose there are good reasons ...

When you have several environment on the same file, be sure that all your points are defined only in your new environment and not on the last one.

\documentclass{article}
\usepackage{tikz} 

\begin{document}

\begin{tikzpicture}
\coordinate (a) at (1,2);
\coordinate (b) at (1,3);
\coordinate (c) at (1,4);
% save 
\end{tikzpicture}

\begin{tikzpicture}
  \foreach \c in {a,...,c}{ \fill[red] (\c) circle (1.5 pt); }
\end{tikzpicture}

\begin{tikzpicture}
\coordinate (a) at (2,2);
\coordinate (b) at (2,3);
\coordinate (c) at (2,4);
 \foreach \c in {a,...,c}{ \fill[blue] (\c) circle (1.5 pt); }
\end{tikzpicture}

%restore I would like to use the same nodes like at the beginning
\begin{tikzpicture}
  \foreach \c in {a,...,c}{ \fill[red] (\c) circle (1.5 pt); } % with 
\end{tikzpicture}
\end{document}

There is a possibility to erase all the points between two "tikzpictures" with

\begin{tikzpicture}
    \foreach \p in {a,b,c,pta,ptb,ptc}{\pgfnoderename{}{\p}}
    % \draw (a) -- (b) ;
    % Latex Error: ./nested_cs.tex:59 Package pgf Error: No shape named a is known.
\end{tikzpicture}

B] Example 2 It's the main problem for me. With macros or control sequences. Some explanations about the next code. \tr``\drawpointsand \labelpointsare only here to control the results

The three macros

  • the first one \subone takes three points here a, b and c and fine some midpoints here pta, ptb and ptc

  • then \subtwo uses also pta, ptb and ptc I want to limit the number of temporary points

  • and \main this macro uses the two last macros \subone and \subtwo. With \subtwoI lose pta, ptb and ptc defined in \subone.

Between two macros the problem is: I need to use pta, ptb and ptc in a macro to define an object and this macro calls another macro that uses also pta, ptb and ptc. Some side effects arrive ... I think it's difficult to solve the problem with the names of nodes but perhaps there is a solution with \pta, \ptb etc.

My question is to find a way to save the first pta, ptb and ptc and restore them at the end of \subtwo

  \documentclass{article}
  \usepackage{tikz} 
  \usetikzlibrary{quotes}
  %-------------------------------------------------------------
  \def\tr[#1](#2,#3,#4){\draw[#1] (#2) -- (#3) -- (#4) --cycle;}
  \def\drawpoints(#1){%
    \foreach \pt in {#1} {\fill (\pt) circle (2 pt);}}
  \def\labelpoints(#1){%
    \foreach \pt in {#1} {\path  coordinate["\pt" below] () at (\pt) ;}}
   %-------------------------------------------------------------           
   \def\subone(#1,#2,#3){% the macro defines midpoints of #1#2 #1#3 and #2#3
     \path[coordinate](barycentric cs:#1=1,#2=1) coordinate (ptc);
     \path[coordinate](barycentric cs:#1=1,#3=1) coordinate (ptb);
     \path[coordinate](barycentric cs:#2=1,#3=1) coordinate (pta);
      }
   %-------------------------------------------------------------
   \def\subtwo(#1,#2,#3){% the macro defines the centroid of (#1,#2,#3)
    % then some symetric points and the last one result
     \path[coordinate](barycentric cs:#1=1,#2=1,#3=1)coordinate (ptd);
     \path[coordinate](barycentric cs:#1=1,ptd=-2)       coordinate (pta);
     \path[coordinate](barycentric cs:#2=1,ptd=-2)       coordinate (ptb);
     \path[coordinate](barycentric cs:#3=1,ptd=-2)       coordinate (ptc);
     \path[coordinate](barycentric cs:pta=1,ptb=1,ptc=-1) coordinate (result);  
}
 %-------------------------------------------------------------
 \def\main(#1,#2,#3){%
    \subone(#1,#2,#3) % call to the first macro
    \subtwo(pta,ptb,ptc) % subtwo affects the values of pta,... etc.
    \draw (result) -- (pta) (result) -- (ptb) (result) -- (ptc);
 }
 \begin{document}
    \begin{tikzpicture}
    \path    coordinate (a) at (0,1)
             coordinate (b) at (5,2)
             coordinate (c) at (1,6);
     \tr[red](a,b,c)
     \subone(a,b,c)
     \drawpoints(a,b,c)
     \drawpoints(pta,pt...,ptc) % this is a test midpoints are defined
     \labelpoints(pta,pt...,ptc)

    %     \subtwo(a,b,c) % test subtwo is correct
    % \drawpoints(pta,pt...,ptd,result)
    % \labelpoints(pta,pt...,ptd,result)
    % \tr[blue](pta,ptb,ptc)

    \main(a,b,c)
    \drawpoints(pta,pt...,ptc)
    \tr[green](pta,ptb,ptc)
    \labelpoints(pta,pt...,ptd,result) 
    \end{tikzpicture}

 \end{document}

C] Research

I try different things. The first idea is to use tools from tikz/pgf like \pgfnodealias and pgfnoderename but here these macros seems to be
inefficacious.

With \pgfnodealias{n_pta}{pta} n_pta points to ptabut when pta is redefined then n_pta points to the new value so I lose the old one.

With \pgfnoderename{n_pta}{pta} n_ptareplaces 'pta`and this one is lost !

Next idea : I tried to use macros to stock the coordinates. I think that is the solution but I miss something ... For example the next code (I'm not sure if it's correct) can save the coordinates

\makeatletter
\newdimen\pt@xa
\newdimen\pt@ya
\def\SavedCoordPoint#1#2{%
    \pgfextractx{\pt@xa}{\pgfpointanchor{#2}{center}}%
    \pgfextracty{\pt@ya}{\pgfpointanchor{#2}{center}}%
    \pgfextract@process\tkzsavepoint{\pgfpoint{\pt@xa}{\pt@ya}}%
    \global\expandafter\edef\csname #1\endcsname{\tkzsavepoint}% 
}
\makeatother
% ex \SavedCoordPoint{pta}{pta}

Perhaps this code can be rewritten but the idea is to save the coordinates of pta into the macro \pta. Now I need to rewrite all my codes because I need to use the macros and not the name of nodes.

Perhaps another macro is useful \pgf@process to restore the coordinates.

D] Concrete example

To get the euler center of a triangle ABC I need

1) to get CentroidTriangle of (A,B,C) with \tkzDefCentroidTriangle(A,B,C){tkz@pta,tkz@ptb,tkz@ptc} {tkz@pta,tkz@ptb,tkz@ptc} are the midpoints of each segment.

2) then I need to get the circumcenter of {tkz@pta,tkz@ptb,tkz@ptc} \tkzCircumCenter(tkz@pta,tkz@ptb,tkz@ptc)

3) to get the circumcenter I need to get some mediator lines ... etc

and in each call I need to use temporary points. No problem is I use different names (nodes) but the code fails I change that. A good idea at the beginning of each macro is to save {tkz@pta,tkz@ptb,tkz@ptc} then to use them and then to restore them before quitting. But How to do this ?

16
  • Would using tikz's node name prefixing system work? Add a prefix for each tikzpicture and then when you need to reuse the nodes, simply reuse the prefix. May 1, 2016 at 21:26
  • @LoopSpace No I think because adding a prefix is like a new name and the number of names increases ... I have dozens of macros and in each macro I need temporary points. I can prefix them and actually I use a suffix ... but I would like to use the same points in each case. but at the end of each macro I need to restore the coordinates of each points May 1, 2016 at 22:02
  • Okay, second thought then. What, exactly, do you want to save? Is it just the coordinate or do you want the ability to use more general nodes (so then you need to save the node type and other information)? May 1, 2016 at 22:09
  • @LoopSpace I added an example for some macros May 1, 2016 at 22:19
  • 1
    Do you want the same absolute positions on the page? So that picture 4 is created on top of picture 2? Or do you mean that you want the same coordinates relative to the current picture's coordinate system?
    – cfr
    May 1, 2016 at 22:54

2 Answers 2

8

If I understand correctly, you want to use the relative positions of the saved nodes in your new picture. That is, each node should refer to a position in the new picture relative to the new origin.

Here's some code that saves all the data for a list of specified nodes which can then be restored at a later time in the document. It uses LaTeX3 stuff internally since it's more about programming and expansion and L3 makes that sooo much easier.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/307356/86}
\usepackage{tikz} 
\usepackage{xparse}

\ExplSyntaxOn

% We save our information in a ``property list'', which is L3's
% version of an associative array or dictionary.  They keys will give
% the ability to store several groups of nodes and restore them at
% will.
\prop_new:N \g__sn_prop
% We'll need a token list for constructing the saved data.
\tl_new:N \l__sn_tmpa_tl

% This is the command that actually does the work.  It constructs a
% token list which contains the code that will restore the node data
% when invoked.  The two arguments are the name of this group (for
% reference later) and a comma separated list of the node names to be
% saved.
\cs_new_nopar:Npn \save_nodes:nn #1#2
{
  % Clear our token list
  \tl_clear:N \l__sn_tmpa_tl
  % Iterate over the list of node names
  \clist_map_inline:nn {#2}
  {
    % Before we start trying to save the node, check that it exists.
    % The macro \pgf@sh@ns@nodename is only defined if that node exists.
    \tl_if_exist:cT {pgf@sh@ns@##1}
    {
      % The node information is stored in a series of macros of the form
      % \pgf@sh@XX@nodename where XX is one of the following.
      \clist_map_inline:nn {ns,np,ma,nt,pi}
      {
        % Our token list will look like:
        %
        % \tl_set:cn {pgf@sh@XX@nodename} {<current contents of that macro>}
        %
        % This will restore \pgf@sh@XX@nodename to its current value
        % when this list is invoked.
        %
        % This part puts the \tl_set:cn {pgf@sh@XX@nodename} in place
        \tl_put_right:Nn \l__sn_tmpa_tl
        {
          \tl_set:cn {pgf@sh@####1@##1}
        }
        % Now we put the current contents in place.  We're doing this in
        % an expansive context to get at the contents.  The \exp_not:v
        % part takes the current value of \pgf@sh@XX@nodename and puts
        % it in place, preventing further expansion.
        \tl_put_right:Nx \l__sn_tmpa_tl {{\exp_not:v {pgf@sh@####1@##1}}}
      }
    }
  }
  % Once we've assembled our token list, we store it in the property
  % list using the key we were given.
  \prop_gput:NnV \g__sn_prop {#1} \l__sn_tmpa_tl
}

\cs_new_nopar:Npn \restore_nodes:n #1
{
  % Restoring nodes is simple: look in the property list for the key
  % and if it exists, invoke the macro stored there.
  \prop_get:NnNT \g__sn_prop {#1} \l__sn_tmpa_tl
  {
    \tl_use:N \l__sn_tmpa_tl
  }
}

% These two are wrappers around our internal commands.
%
% The first argument is the label for our group of nodes (so that we
% can refer to them later) and the second argument is a comma
% separated list of nodes to save.
\DeclareDocumentCommand \SaveNodes {m m}
{
  \save_nodes:nn {#1}{#2}
}

% The argument to this is the label for our group of nodes to restore.
\DeclareDocumentCommand \RestoreNodes {m}
{
  \restore_nodes:n {#1}
}

\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
\coordinate (a) at (1,2);
\coordinate (b) at (1,3);
\coordinate (c) at (1,4);
% save
\SaveNodes{here}{a,b,c}
\end{tikzpicture}

\begin{tikzpicture}
\fill[black] (0,0) circle (1.5 pt);
  \foreach \c in {a,...,c}{ \fill[red] (\c) circle (1.5 pt); }
\end{tikzpicture}

\begin{tikzpicture}
\coordinate (a) at (2,2);
\coordinate (b) at (2,3);
\coordinate (c) at (2,4);
\fill[black] (0,0) circle (1.5 pt);
 \foreach \c in {a,...,c}{ \fill[blue] (\c) circle (1.5 pt); }
\end{tikzpicture}

%restore I would like to use the same nodes like at the beginning
\begin{tikzpicture}
\RestoreNodes{here}
\fill[black] (0,0) circle (1.5 pt);
  \foreach \c in {a,...,c}{ \fill[red] (\c) circle (1.5 pt); } % with 
\end{tikzpicture}
\end{document}

I added the black circles at the origin to show that it is the original nodes that are used, not the new ones. I think I'm saving all the information about the nodes, not just their coordinates, so this solution would work with general nodes not just coordinates. With a little more work, it would be possible to take a list of nodes at the restore stage and only restore those.

Saved node positions

Here's a non-L3 version. It works on a per-node basis (but you could probably wrap it if the nodes always have the same names).

\makeatletter

\def\@savecoord#1#2{%
  \expandafter\let\expandafter\sn@temp\csname pgf@sh@#1@#2\endcsname
  \expandafter\def\expandafter\sn@tempb\expandafter{%
    \expandafter\gdef\csname pgf@sh@#1@#2\expandafter\endcsname\expandafter{%
      \sn@temp
    }%
  }%
  \expandafter\g@addto@macro\expandafter\sn@tempa\expandafter{\sn@tempb}%
}

% {ns,np,ma,nt,pi}
\def\savecoordinate#1#2{%
  \def\sn@tempa{}%
  %
  \@savecoord{ns}{#2}%
  \@savecoord{np}{#2}%
  \@savecoord{ma}{#2}%
  \@savecoord{nt}{#2}%
  \@savecoord{pi}{#2}%
%
  \expandafter\global\expandafter\let\csname sn@#1\endcsname\sn@tempa
}

\def\restorecoordinate#1{%
  \csname sn@#1\endcsname
}

\makeatother
13
  • I change the tags because you are perfectly right it's more a problem about expansion and programming. Perhaps it's for me a good reason to try to learn L3 :) May 2, 2016 at 10:40
  • @AlainMatthes I've added some comments to the code. Some understanding of basic L3 syntax might be useful: tl refers to token lists, clist to comma separated lists, prop to property lists, and cs to commands. May 2, 2016 at 11:46
  • I try you code with my example 2 and It's fine. Now I try it on my new version of tkz-euclide and I get a mistake : ./test_Sp.tex:14: Undefined control sequence. <argument> \LaTeX3 error: Erroneous variable \pgf@sh@ns@tkzpta used! l.14 \tkzCircumCenter(A,B,C). It's difficult for me to search an error because I don't understand the code. May 2, 2016 at 11:50
  • I'd need the exact code to test it. May 2, 2016 at 11:54
  • I found a way. I need to define the temporary nodes at he beginning of my document \coordinate (tkz@pta) at (0,0) ; etc for the five temporary nodes because if I use a sub macro directly thesis nodes are not defined. How to do this properly ? is it possible from your code ? May 2, 2016 at 13:07
1

Another approach is to create a stack that contains the nodes for a macros. Each call to a macro create en new level in the stack, and the level is deleted at the end of the macro. One can preserve the nodes one chooses by picking them, and only ones that are useful for the future.

One declares some nodes (human readable names) at the beginning of the macro, they will act as local nodes: they don't overwrite an existing node and vanished at the end of the macro. The declaration order must be the same as the output list order.

Therefore there is no confusion or loss in multiple calls of macros.

All nodes are calculated in one macro, the drawing is optional :

\CercleEuler[o,I,J,K,P1,P2,P3,J1,J2,J3,G,H,O]{%
     a,b,c}<fill=lightgray!20,draw=gray,semithick>

enter image description here

\documentclass{article}
\usepackage{tikz,xparse} 
\usetikzlibrary{quotes,through,calc}

\ExplSyntaxOn
\NewDocumentCommand{\ExtractFromList}{%
    m % macro
    m % list
    m % number : -1 for the last 
    }
 {
  \tl_set:Nx #1 {\clist_item:Nn #2 { #3 } }
 }

\NewDocumentCommand{\NewPoints}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \cs_set:cpx { ##1 } { a-\NumNode-\theLittNode }
    \stepcounter{LittNode}
   }
 }
\ExplSyntaxOff

% counter for naming nodes
\newcounter{LittNode}

% level of calling
\pgfmathtruncatemacro{\NumNode}{0}

% node named #1 at the current level
\def\N#1{a-\NumNode-#1}

\makeatletter % ------------------------ #### Make @ Letter

% -------------------------------------- #### AtBeginTikzMacro
\newcommand{\AtBeginTikzMacro}[1]{%
    \pgfmathtruncatemacro{\NumNode}{\NumNode+1}
    \expandafter\edef\csname OutPut-\NumNode\endcsname{#1}
    \setcounter{LittNode}{1}
    \begingroup % au début de chaque macro
}

% -------------------------------------- #### KeepUsefullNodes
\newcommand{\KeepUsefullNodes}{%
    \endgroup   % à la fin de chaque macro
    \edef\Sortie{\csname OutPut-\NumNode \endcsname}
    \foreach \Nd [count=\i from 1]
        in \Sortie {%
        \coordinate (\Nd) at (\N{\i}) ;
    }
    \pgfmathtruncatemacro{\NumNode}{\NumNode-1}
}

%-----------------------------------------------------------
\def\tr[#1](#2,#3,#4){\draw[#1] (#2) -- (#3) -- (#4) --cycle;}
\def\drawpoints(#1){%
\foreach \pt in {#1} {\fill (\pt) circle (2 pt);}}
\def\labelpoints(#1){%
\foreach \pt in {#1} {\path  coordinate["\pt" below] () at (\pt) ;}}
%-----------------------------------------------------------

% #### --------------------------------- #### NodeAngle ####
    % #1 premier point
    % #2 second point
    % On récupère le résultat dans \MyAngle
\newcommand{\NodeAngle}[3][\MyAngle]{%
    \pgfextra{
        \pgfmathanglebetweenpoints%
            {\pgfpointanchor{#2}{center}}%
            {\pgfpointanchor{#3}{center}}%
            \global\let#1\pgfmathresult
    }}

% #### --------------------------------- #### NodeDist ####
    % #1 premier point
    % #2 second point
    % On récupère le résultat dans \MyDist
\newcommand{\NodeDist}[3][\MyDist]{%
    \pgfpointdiff{\pgfpointanchor{#2}{center}}
                 {\pgfpointanchor{#3}{center}}
    % no need to use a new dimen
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    % to convert from pt to cm   
    \pgfmathparse{veclen(\pgf@xa,\pgf@ya)/28.45274}
    \global\let#1\pgfmathresult % we need a global macro    
}

% #### --------------------------------- #### AngleBAC ####
\newcommand{\AngleBAC}[2][A]{%
    \begingroup

    \edef\List{#2}
    \ExtractFromList\A\List{2}
    \ExtractFromList\B\List{1}
    \ExtractFromList\C\List{3}

    \pgfmathanglebetweenpoints
    {\pgfpointanchor{\A}{center}}
    {\pgfpointanchor{\B}{center}}
    \let\Angl@A\pgfmathresult ;

    \pgfmathanglebetweenpoints
    {\pgfpointanchor{\A}{center}}
    {\pgfpointanchor{\C}{center}}
    \let\Angl@B\pgfmathresult ;

    \pgfmathparse{\Angl@B-\Angl@A}
    \let\Angl@A\pgfmathresult ;
    \expandafter\xdef\csname angle#1\endcsname{\Angl@A}

    \pgfmathparse{cos(\Angl@A)}
    \expandafter\xdef\csname Cos#1\endcsname{\pgfmathresult}
    \pgfmathparse{sin(\Angl@A)}
    \expandafter\xdef\csname Sin#1\endcsname{\pgfmathresult}
    \pgfmathparse{tan(\Angl@A)}
    \expandafter\xdef\csname Tan#1\endcsname{\pgfmathresult}

    \endgroup
}

% #### --------------------------------- #### Milieux ####
\NewDocumentCommand{\Milieux}{%
    s   % * liste de segments, polygone sinon
    O{} % liste de retour
    m   % liste d'entrée
    }{%
    \AtBeginTikzMacro{#2}
    \IfBooleanTF{#1}{%
        % On peut utiliser foreach, mais il ne faut jamais
        % que les noms de variables croisent les noms des nodes
    \foreach \A@/\B@ in {#3} {%
        % On utilise le même nom de macro,
        % mais elle pointe à chaque fois un nouveau nom de node.
        % A la fin on récupère les noms de node
        % pas le nom des macros.
        % On utilisera le même truc à chaque fois que
        % c'est possible.

        % On déclare un node local ou un liste à la fois,
        % sans le \
    \NewPoints{Milieu}
        % Dans une macro, le nom des nodes locaux sont utilisés
        % avec un \ puisque que ce sont des macros
    \coordinate  (\Milieu) at (barycentric cs:\A@=1,\B@=1) ;
        }
    }{%
        \def\List{#3}
        \ExtractFromList\Lastx\List{-1}
        \foreach \x@
            [remember=\x@ as \lastx (initially \Lastx)] in {#3} {%
        \NewPoints{Milieu}
        \coordinate  (\Milieu) at (barycentric cs:\lastx=1,\x@=1) ;
        }
    }
    \KeepUsefullNodes
}

% #### --------------------------------- #### DtEuler ####
\newcommand{\DtEuler}[2][]{%
    \AtBeginTikzMacro{#1}

    \NewPoints{G,H,O}

    \edef\List{#2}
    \ExtractFromList\A\List{1}
    \ExtractFromList\B\List{2}
    \ExtractFromList\C\List{3}

    % Calcul des tangentes
    \AngleBAC[@A]{\B,\A,\C}
    \AngleBAC[@B]{\C,\B,\A}
    \AngleBAC[@C]{\A,\C,\B}

    % isobarycentre
    \coordinate  (\G) at (barycentric cs:\A=1,\B=1,\C=1) ;

    % horthocentre
    \coordinate (\H) at (barycentric
                        cs:\A=\Tan@A,\B=\Tan@B,\C=\Tan@C) ;

    % centre du cercle circonscrit
    \coordinate (\O) at (barycentric
            cs:\A=\Tan@B+\Tan@C,\B=\Tan@A+\Tan@C,\C=\Tan@A+\Tan@B) ;

    \KeepUsefullNodes
}

% #### --------------------------------- #### ProjMAB ####
\NewDocumentCommand{\ProjMAB}{O{}m}{%
    \AtBeginTikzMacro{#1}

    \NewPoints{H}

    \edef\List{#2}
    \ExtractFromList\M\List{1}
    \ExtractFromList\A\List{2}
    \ExtractFromList\B\List{3}

    % Calcul des tangentes
    \AngleBAC[@MAB]{\M,\A,\B}
    \AngleBAC[@MBA]{\A,\B,\M}

    % horthocentre
    \coordinate (\H) at (barycentric
                    cs:\A=\Tan@MAB,\B=\Tan@MBA) ;

    \KeepUsefullNodes
}

\makeatother % ------------------------- #### Make @ Other

% #### --------------------------------- #### ProjABC ####
\NewDocumentCommand{\ProjABC}{O{}m}{%
    \AtBeginTikzMacro{#1}

    \NewPoints{I,J,K}

    \def\List{#2}
    \ExtractFromList\B\List{2}
    \ExtractFromList\C\List{3}

    \ProjMAB[\J]{#2}
    \ProjMAB[\I]{\C,#2}
    \ProjMAB[\K]{\B,\C,#2}

    \KeepUsefullNodes
}

% #### --------------------------------- #### CercleABC ####
\NewDocumentCommand{\CercleABC}{%
    O{} % centre
    m   % A,B,C
    D<>{}   % option pour draw
    }{%

    \AtBeginTikzMacro{#1}

    \NewPoints{O}

    \edef\List{#2}
    \ExtractFromList\A\List{1}
    \ExtractFromList\B\List{2}
    \ExtractFromList\C\List{3}

    \DtEuler[,,\O]{\A,\B,\C}

    \node[circle through=(\A),#3] at (\O) {};

    \KeepUsefullNodes
}

% #### --------------------------------- #### CercleEuler ####
\NewDocumentCommand{\CercleEuler}{%
    O{} % renvoie dans l'ordre:
        % le centre,
        % 3 milieux,
        % 3 projetés,
        % 3 milieux orthocentre-sommet
        % G,H,O
    m   % A,B,C
    D<>{}   % option pour draw
    }{%

    \AtBeginTikzMacro{#1}

    \NewPoints{o,I,J,K,P,Q,R,p,q,r,G,H,O}

    \edef\List{#2}
    \ExtractFromList\A\List{1}
    \ExtractFromList\B\List{2}
    \ExtractFromList\C\List{3}

    \Milieux[\J,\K,\I]{\A,\B,\C}
    \DtEuler[\G,\H,\O]{\A,\B,\C}
    \ProjABC[\R,\P,\Q]{a,b,c}
    \CercleABC[\o]{\I,\J,\K}<#3>
    \Milieux*[\p,\q,\r]{\H/\A,\H/\B,\H/\C}

    \KeepUsefullNodes
}

\tikzset{%
    small dot/.style 2 args={fill=#1,circle,scale=#2},
    small dot/.default={black}{.3},
}

\NewDocumentCommand{\Droite}{%
    O{} % #1 option du path
    m   % #2 premier point sans ()
    m   % #3 second point sans ()
    m   % #4 longueur dans un sens
    m   % #5 longueur dans l'autre
    }{%
        \path[#1] ($(#3)!#4!(#2)$) -- ($(#2)!#5!(#3)$) ;
}

% #1 taille du carré defaut 5pt
% #2 Argument boucle foreach             ---- Angle droit ----
% Point / Angle droit / Point
\NewDocumentCommand{\AngleDt}{
    s       % angle droite simple avec deux points
    D<>{very thin}      % option path
    O{5pt}  % taille du carré
    m       % liste de triplets ou de couples (*)
    }{%
    \IfBooleanTF{#1}{%
    \foreach \B/\A in {#4} {%
        \draw[#2] ($(\B)!#3!(\A)$)
        --($ (\B)!2!($($(\B)!#3!(\A)$)!.5!($(\B)!#3!#190:(\A)$)$)$)
        --($(\B)!#3!#190:(\A)$) ; }
    }{%
    \foreach \A/\B/\C in {#4} {%
        \draw[#2] ($(\B)!#3!(\A)$)
        --($ (\B)!2!($($(\B)!#3!(\A)$)!.5!($(\B)!#3!(\C)$)$) $)
        --($(\B)!#3!(\C)$) ; }
    }
}


\begin{document}

\begin{tikzpicture}[scale=1.1]

\coordinate (a) at (0,1) ;
\coordinate (b) at (7,1) ;
\coordinate (c) at (1,6.4) ;


\CercleEuler[o,I,J,K,P1,P2,P3,J1,J2,J3,G,H,O]{%
    a,b,c}<fill=lightgray!20,draw=gray,semithick>

\tr[black](a,b,c)

\Droite[draw,blue,semithick]{H}{O}{1.6}{1.6}

\Droite[draw,yellow!95!black,semithick,dashed]{I}{O}{1.4}{1.5}
\Droite[draw,yellow!95!black,semithick,dashed]{J}{O}{1.2}{1.2}
\Droite[draw,yellow!95!black,semithick,dashed]{K}{O}{1.2}{1.2}

\draw[draw,red,dashed] (a)--(P1) (b)--(P2) (c)--(P3) ;

\draw[green,dashed] (a)--(I) (b)--(J) (c)--(K) ;

\AngleDt{a/P1/b,b/P2/c,c/P3/a,O/I/c,O/J/a,O/K/b}

\foreach \Coor/\Text/\Pos in 
    {a/$A$/-135,
    b/$B$/-45,
    c/$C$/90,
    I/$I$/20,
    J/$J$/130,
    K/$K$/-50,
    P1/$p_1$/60,
    P2/$p_2$/190,
    P3/$p_3$/-120,
    J1/$j_1$/180,
    J2/$j_2$/-60,
    J3/$j_3$/130,
    G/$G$/-110,
    H/$H$/130,
    O/$O$/-50,
    o/$O'$/130
    } {
    \node[small dot] at (\Coor) {} ;
    \node[shift=(\Pos:8pt),anchor=center] at (\Coor) {\small\Text} ;
    }

\end{tikzpicture}
\end{document}
5
  • Interesting! I need to study your code slowly but I appreciate the comment :"Therefore there is no confusion or loss in multiple calls of macros." May 4, 2016 at 15:39
  • 1
    L'idée est que chaque macro a ses nodes N{i} qu'elle peut passer à la suivante qui peut lui renvoyer les siens, mais l'une ne peut pas modifier ceux de l'autre. Donc plus besoin de sauvegarder ou de restaurer les nodes. Tout se passe comme si les N{i} étaient des variables locales, à condition de bien respecter l'usage de N{i} et Np{i}. Si tu vois comment améliorer le fait que l'on soit obligé d'utiliser des Np{i} pour passer des nodes à la macro suivantes (à cause de l'expansion de suppose) et le fait que l'on puisse appeler les nodes N{a} N{b}, je suis intéressé. merci
    – Tarass
    May 5, 2016 at 5:16
  • @AlainMatthes Pour la partie lettre des nodes, j'ai trouvé une solution. Pour la partie expansion, j'ai posé une question : tex.stackexchange.com/questions/307983/expansion-problem
    – Tarass
    May 5, 2016 at 7:16
  • Nous pouvons peut-être continuer en français par mail (voir mon email sur mon site ) May 5, 2016 at 7:19
  • I just send you an email to the adress at the very bottom right of you site, I had trouble to find it ;-)
    – Tarass
    May 5, 2016 at 8:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .