%%%
% Rose
%%%
\setKVdefault[ClesRose]{Vide=false,Couleur=white,Produits=false,Solution=false,Rayon=2cm,Petales=7,Aide=false,FacteurMin=2,FacteurMax=10,ProduitVide=false,CaseVide=false,Polygone=false,Nom=Rose1}%

\NewDocumentCommand\RoseMul{o}{%
  \useKVdefault[ClesRose]%
  \setKV[ClesRose]{#1}%
  \ifluatex%
  \ifboolKV[ClesRose]{Solution}{%
    \DessineRoseMulSol%
  }{%
    \DessineRoseMul%
  }%
  \else%
  \DessineRoseMul%
  \fi%
}%

\newcommand\DessineRoseMulSol{%
  \ifluatex%
  \mplibforcehmode%
  \xdef\PfCNomRose{\useKV[ClesRose]{Nom}}%
  \begin{mplibcode}[\PfCNomRose]
    boolean Aide,Produits,Solution,Vide,ProduitVide,CaseVide,Polygone;
    Aide:=\useKV[ClesRose]{Aide};
    Vide:=\useKV[ClesRose]{Vide};
    Solution:=\useKV[ClesRose]{Solution};
    Produits:=\useKV[ClesRose]{Produits};
    ProduitVide:=\useKV[ClesRose]{ProduitVide};
    CaseVide:=\useKV[ClesRose]{CaseVide};
    if ProduitVide:Solution:=true fi;
    if CaseVide:Solution:=true fi;
    % on labelise
    if Vide=false:
    if Produits:
    else:
    for k=0 upto Petales-1:
    label(TEX("\num{"&decimal(Facteur[k])&"}"),(0.5[O,A[k]]-center BoiteRec));
    endfor;
    fi;
    if Produits or Solution:
    for k=0 upto Petales-1:
    label(TEX("\num{"&decimal(Produit[k])&"}"),(B[k]+0.5*Rayon*unitvector(B[k])));
    endfor;
    fi;
    fi;
    % On trace et on affiche...éventuellement :)
    if Aide:
    for k=0 upto Petales-1:
    drawarrow (0.5[O,A[k]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    drawarrow (0.5[O,A[k+1]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
    fi;
    if ProduitVide:
    %choix=floor(uniformdeviate(Petales-1));
    fill (BoiteRec shifted (1.75[O,B[choix]]-center BoiteRec)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,(choix-1)*(360/Petales)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,choix*(360/Petales)) withcolor Fond;
    fi;
    if CaseVide:
    %choix:=floor(uniformdeviate(Petales-1));
    for k=0 upto Petales-1:
    if k<>choix:
    fill rotation(polygone(O,B0,A1,B1),O,k*(360/Petales)) withcolor Fond;
    fi;
    endfor;
    fi;
    trace A0 for k=1 upto Petales:--A[k] endfor --cycle;
    for k=0 upto Petales-1:
    trace segment(O,B[k]) dashed withdots scaled 0.25;
    draw BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
  \end{mplibcode}
  \fi
}
\newcommand\DessineRoseMul{%
  \ifluatex%
  \mplibforcehmode%
  \xdef\PfCNomRose{\useKV[ClesRose]{Nom}}%
  \begin{mplibcode}[\PfCNomRose]
    vardef ExtraireListe(expr nbmin,nbmax,nbfacteurs)=
    numeric ElementE[],ElementS[];
    %% éléments d'entrée
    nbe:=1;
    for k=nbmin upto nbmax:
    ElementE[nbe]=k;
    nbe:=nbe+1;
    endfor;
    totalE:=(nbmax-nbmin)+1;
    numeric rec;
    for k=1 upto nbfacteurs:
    rec:=ceiling(uniformdeviate(totalE+1-k));
    ElementS[k]=ElementE[rec];
    numeric ElementI[];
    p:=0;
    for l=1 upto totalE+1-k:
    if l<>rec:
    p:=p+1;
    ElementI[p]=ElementE[l];
    fi;
    endfor;
    numeric ElementE[];
    for l=1 upto p:
    ElementE[l]=ElementI[l];
    endfor;
    endfor;
    enddef;
    pair A[],B[],O;
    Rayon:=\useKV[ClesRose]{Rayon};
    boolean Aide,Produits,Solution,Vide,ProduitVide,CaseVide,Polygone;
    Aide:=\useKV[ClesRose]{Aide};
    Vide:=\useKV[ClesRose]{Vide};
    Solution:=\useKV[ClesRose]{Solution};
    Produits:=\useKV[ClesRose]{Produits};
    ProduitVide:=\useKV[ClesRose]{ProduitVide};
    CaseVide:=\useKV[ClesRose]{CaseVide};
    if ProduitVide:Solution:=true fi;
    if CaseVide:Solution:=true fi;
    Polygone:=\useKV[ClesRose]{Polygone};
    Petales:=\useKV[ClesRose]{Petales};
    FacteurMin:=\useKV[ClesRose]{FacteurMin};
    FacteurMax:=\useKV[ClesRose]{FacteurMax};
    color Fond;
    Fond:=\useKV[ClesRose]{Couleur};
    O=(0,0);
    ExtraireListe(FacteurMin,FacteurMax,Petales);
    path cc;
    cc=cercles(O,Rayon);
    for k=0 upto Petales:
    A[k]=pointarc(cc,(360/Petales)*k);
    endfor;
    for k=0 upto Petales-1:
    B[k]=iso(A[k],A[k+1]);
    endfor;
    path BoiteRec;
    if Polygone:
    BoiteRec=(pointarc(fullcircle,0) for k=1 upto Petales:--pointarc(fullcircle,k*(360/Petales)) endfor --cycle) scaled 1u;
    else:
    BoiteRec=((-0.4,-0.5)--(0.4,-0.5){dir0}..{dir90}(0.5,-0.4)--(0.5,0.4){dir90}..{dir180}(0.4,0.5)--(-0.4,0.5){dir180}..{dir-90}(-0.5,0.4)--(-0.5,-0.4){dir-90}..cycle) scaled 1u;
    fi;    
    %On détermine les facteurs et produits
    for k=0 upto Petales-1:
    Facteur[k]:=ElementS[k+1];
    endfor;
    Facteur[Petales]:=Facteur[0];
    for k=0 upto Petales-1:
    Produit[k]:=Facteur[k]*Facteur[k+1];
    endfor;
    %on labelise
    if Vide=false:
    if Produits:
    else:
    for k=0 upto Petales-1:
    label(TEX("\num{"&decimal(Facteur[k])&"}"),(0.5[O,A[k]]-center BoiteRec));
    endfor;
    fi;
    if Produits or Solution:
    for k=0 upto Petales-1:
    label(TEX("\num{"&decimal(Produit[k])&"}"),(B[k]+0.5*Rayon*unitvector(B[k])));
    endfor;
    fi;
    fi;
    % On trace et on affiche...éventuellement :)
    if Aide:
    for k=0 upto Petales-1:
    drawarrow (0.5[O,A[k]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    drawarrow (0.5[O,A[k+1]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
    fi;
    if ProduitVide:
    choix:=floor(uniformdeviate(Petales-1));
    fill (BoiteRec shifted (1.75[O,B[choix]]-center BoiteRec)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,(choix-1)*(360/Petales)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,choix*(360/Petales)) withcolor Fond;
    fi;
    if CaseVide:
    choix:=floor(uniformdeviate(Petales-1));
    for k=0 upto Petales-1:
    if k<>choix:
    fill rotation(polygone(O,B0,A1,B1),O,k*(360/Petales)) withcolor Fond;
    fi;
    endfor;
    fi;
    trace A0 for k=1 upto Petales:--A[k] endfor --cycle;
    for k=0 upto Petales-1:
    trace segment(O,B[k]) dashed withdots scaled 0.25;
    draw BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
  \end{mplibcode}
  \else
  \begin{mpost}[mpsettings={Rayon:=\useKV[ClesRose]{Rayon};
    boolean Aide,Produits,Solution,Vide,ProduitVide,CaseVide,Polygone;
    Aide:=\useKV[ClesRose]{Aide};
    Vide:=\useKV[ClesRose]{Vide};
    Solution:=\useKV[ClesRose]{Solution};
    Produits:=\useKV[ClesRose]{Produits};
    ProduitVide:=\useKV[ClesRose]{ProduitVide};
    CaseVide:=\useKV[ClesRose]{CaseVide};
    if ProduitVide:Solution:=true fi;
    if CaseVide:Solution:=true fi;
    Polygone:=\useKV[ClesRose]{Polygone};
    Petales:=\useKV[ClesRose]{Petales};
    FacteurMin:=\useKV[ClesRose]{FacteurMin};
    FacteurMax:=\useKV[ClesRose]{FacteurMax};
    color Fond;
    Fond:=\useKV[ClesRose]{Couleur};}]
    vardef ExtraireListe(expr nbmin,nbmax,nbfacteurs)=
    numeric ElementE[],ElementS[];
    %% éléments d'entrée
    nbe=1;
    for k=nbmin upto nbmax:
    ElementE[nbe]=k;
    nbe:=nbe+1;
    endfor;
    totalE=(nbmax-nbmin)+1;
    numeric rec;
    for k=1 upto nbfacteurs:
    rec:=ceiling(uniformdeviate(totalE+1-k));
    ElementS[k]=ElementE[rec];
    numeric ElementI[];
    p:=0;
    for l=1 upto totalE+1-k:
    if l<>rec:
    p:=p+1;
    ElementI[p]=ElementE[l];
    fi;
    endfor;
    numeric ElementE[];
    for l=1 upto p:
    ElementE[l]=ElementI[l];
    endfor;
    endfor;
    enddef;
    pair A[],B[],O;
    O=(0,0);
    ExtraireListe(FacteurMin,FacteurMax,Petales);
    path cc;
    cc=cercles(O,Rayon);
    for k=0 upto Petales:
    A[k]=pointarc(cc,(360/Petales)*k);
    endfor;
    for k=0 upto Petales-1:
    B[k]=iso(A[k],A[k+1]);
    endfor;
    path BoiteRec;
    if Polygone:
    BoiteRec=(pointarc(fullcircle,0) for k=1 upto Petales:--pointarc(fullcircle,k*(360/Petales)) endfor --cycle) scaled 1u;
    else:
    BoiteRec=((-0.4,-0.5)--(0.4,-0.5){dir0}..{dir90}(0.5,-0.4)--(0.5,0.4){dir90}..{dir180}(0.4,0.5)--(-0.4,0.5){dir180}..{dir-90}(-0.5,0.4)--(-0.5,-0.4){dir-90}..cycle) scaled 1u;
    fi;    
    %On détermine les facteurs et produits
    for k=0 upto Petales-1:
    Facteur[k]=ElementS[k+1];
    endfor;
    Facteur[Petales]=Facteur[0];
    for k=0 upto Petales-1:
    Produit[k]=Facteur[k]*Facteur[k+1];
    endfor;
    %on labelise
    if Vide=false:
    if Produits:
    else:
    for k=0 upto Petales-1:
    label(LATEX("\num{"&decimal(Facteur[k])&"}"),(0.5[O,A[k]]-center BoiteRec));
    endfor;
    fi;
    if Produits or Solution:
    for k=0 upto Petales-1:
    label(LATEX("\num{"&decimal(Produit[k])&"}"),(B[k]+0.5*Rayon*unitvector(B[k])));
    endfor;
    fi;
    fi;
    % On trace et on affiche...éventuellement :)
    if Aide:
    for k=0 upto Petales-1:
    drawarrow (0.5[O,A[k]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    drawarrow (0.5[O,A[k+1]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
    fi;
    if ProduitVide:
    choix=floor(uniformdeviate(Petales-1));
    fill (BoiteRec shifted (1.75[O,B[choix]]-center BoiteRec)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,(choix-1)*(360/Petales)) withcolor Fond;
    fill rotation(polygone(O,B0,A1,B1),O,choix*(360/Petales)) withcolor Fond;
    fi;
    if CaseVide:
    choix:=floor(uniformdeviate(Petales-1));
    for k=0 upto Petales-1:
    if k<>choix:
    fill rotation(polygone(O,B0,A1,B1),O,k*(360/Petales)) withcolor Fond;
    fi;
    endfor;
    fi;
    trace A0 for k=1 upto Petales:--A[k] endfor --cycle;
    for k=0 upto Petales-1:
    trace segment(O,B[k]) dashed withdots scaled 0.25;
    draw BoiteRec shifted (B[k]+0.5*Rayon*unitvector(B[k])) dashed evenly scaled 0.5;
    endfor;
  \end{mpost}
  \fi
}%