Definizione globale di un colore all’interno di un \foreach

  • Creatore
    Topic
  • #103344
    Liverpool
    Partecipante
      Up
      0
      Down
      ::


      Devo generare 50 disegni. Ciascuno di essi deve contenere 4 forme geometriche con un colore scelto casualmente tra 5. Il problema può essere semplificato in questo modo: devo generare 50 serie di 4 quadretti colorati, ciascuno con un colore casuale scelto tra 5.
      Il codice che ho realizzato è il seguente:
      `\documentclass{article}
      \usepackage{tikz}
      \colorlet{colore1}{gray!20}
      \colorlet{colore2}{gray!40}
      \colorlet{colore3}{gray!60}
      \colorlet{colore4}{gray!80}

      \begin{document}
      \foreach \ciclo in {1,…,50} {
      \foreach \i in {1,…,4} {
      \pgfmathparse{random(5)}
      \ifnum\pgfmathresult = 1
      \colorlet{colore\i}{pink}
      \else\ifnum\pgfmathresult = 2
      \colorlet{colore\i}{red}
      \else\ifnum\pgfmathresult = 3
      \colorlet{colore\i}{green!80!black}
      \else\ifnum\pgfmathresult = 4
      \colorlet{colore\i}{orange}
      \else\ifnum\pgfmathresult = 5
      \colorlet{colore\i}{cyan!95!black}
      \fi\fi\fi\fi\fi
      }
      \noindent
      \colorbox{colore1}{1}\colorbox{colore2}{2}%
      \colorbox{colore3}{3}\colorbox{colore4}{4}
      }
      \end{document}`
      Il problema è che i colori ridefiniti all’interno del ciclo più interno (quello con indice i) sono locali e perciò sono invisibili nel ciclo più esterno. Come fare per risolvere il problema?

      Grazie

    Visualizzazione 5 filoni di risposte
    • Autore
      Risposte
      • #103345
        Up
        0
        Down
        ::


        Non puoi provare a usare il pacchetto xspotcolor? (Vedi anche http://tex.stackexchange.com/q/141245/13304).

        Ciao
        Claudio

      • #103346
        Liverpool
        Partecipante
          Up
          0
          Down
          ::

          cfiandra” post=103370Non puoi provare a usare il pacchetto xspotcolor? (Vedi anche http://tex.stackexchange.com/q/141245/13304).

          Grazie per la risposta, ma non vedo la pertinenza. Il mio problema è fare in modo che i colori che sono definiti all’interno del [tt]foreach[/tt] vengano riconosciuti anche all’esterno. Il disegno con i quadratini colorati è solo un esempio semplificato messo su per mostrare un esempio minimo compilabile senza troppe distrazioni.
          Quello che si vede è una successione di quadratini grigi, mentre dovrebbe essere una successione di quadratini colorati in maniera casuale.

          Ciao

        • #103347
          Up
          0
          Down
          ::

          Liverpool” post=103371

          Non puoi provare a usare il pacchetto xspotcolor? (Vedi anche http://tex.stackexchange.com/q/141245/13304).

          Grazie per la risposta, ma non vedo la pertinenza. Il mio problema è fare in modo che i colori che sono definiti all’interno del [tt]foreach[/tt] vengano riconosciuti anche all’esterno. Il disegno con i quadratini colorati è solo un esempio semplificato messo su per mostrare un esempio minimo compilabile senza troppe distrazioni.
          Quello che si vede è una successione di quadratini grigi, mentre dovrebbe essere una successione di quadratini colorati in maniera casuale.

          Ciao

          Il problema mi era quasi chiaro 😉 Non capisco ancora se vuoi avere una successione di colori completamente casuale o se la vuoi casuale a gruppi di colore, 5 sfumature casuali di grigio, poi di rosa, rosso e così via.

          Se il problema è il primo, allora proverei a vedere di associare il valore casuale generato a ciascun colore “Pantone”.

          Se il problema è il secondo, è un po’ più complicato perché non c’è lo stesso grado di libertà nella scelta del primo problema.

          Per smartdiagram avevo un problema simile (di definire globalmente dei colori) quando cercavo di ridefinire la lista di colori usati in ciascun elemento. Rispetto alla tua soluzione, nel pacchetto si usa [tt]\@namedef[/tt] e [tt]\@nameuse[/tt]. Alla fine, Enrico aveva fornito una soluzione perfetta: How to make global a color list definition with \@namedef done inside a foreach loop. Forse questo meccanismo è più facile da usare.

          Ciao
          Claudio

        • #103348
          Liverpool
          Partecipante
            Up
            0
            Down
            ::


            Ho visto la soluzione che mi proponi (quella di Enrico) e la trovo troppo macchinosa:
            1) devo usare [tt]\@namedef[/tt] all’interno del ciclo al posto di [tt]\colorlet[/tt]
            2) all’esterno del ciclo devo usare [tt]\@nameuse[/tt].

            Domanda secca: non c’è un modo per poter usare direttamente [tt]\colorlet[/tt] o un comando fornito da [tt]xcolor[/tt] all’interno del ciclo?

            Ciao
            `\documentclass{article}
            \usepackage{tikz}
            \makeatletter
            \begin{document}
            \foreach \ciclo in {1,…,50} {
            \foreach \i in {1,…,4} {
            \pgfmathparse{random(5)}
            \ifnum\pgfmathresult = 1
            \global\@namedef{colore\i}{pink}
            \else\ifnum\pgfmathresult = 2
            \global\@namedef{colore\i}{red}
            \else\ifnum\pgfmathresult = 3
            \global\@namedef{colore\i}{green!80!black}
            \else\ifnum\pgfmathresult = 4
            \global\@namedef{colore\i}{orange}
            \else\ifnum\pgfmathresult = 5
            \global\@namedef{colore\i}{cyan!95!black}
            \fi\fi\fi\fi\fi
            }
            \noindent
            \colorbox{\@nameuse{colore1}}{1}\colorbox{\@nameuse{colore2}}{2}%
            \colorbox{\@nameuse{colore3}}{3}\colorbox{\@nameuse{colore4}}{4}
            }
            \makeatother
            \end{document}`

          • #103349
            OldClaudio
            Partecipante
              Up
              0
              Down
              ::


              \colorlet è un comando che associa ad un certo colore un altro nome equivalente al primo.

              \@namedef e \@nameuse sono due comandi che costruiscono un nome di macro “invalido” secondo le regole comuni, perché contengono dei segni che non sono lettere; preceduti da \global le definizioni delle nuove macro con nomi particolari, diventano definizioni globali; \colorlet non ha ninete di globale e preceduto da \global non fa niente di particolare. Dipende, ovviamente, dalla definizione.

              Ma se carichi etoolbox (sempre che non sia già caricato: controlla nel file log che cosa carica il file del tuo documento) disponi di molti comandi privi del segno @ che fanno le cose più incredibili, con definizioni globali e definizioni robuste che possono operare su stringhe come “colore\i” che devono essere sviluppate per deifinire la cosa giusta. Il codice che a tesmbra complicato, diventa almeno più facilmente leggibile e non richiede \makeatletter.

              Tra l’altro il \makeatletter messo subito prima di \begin{document}, come nel codice che hai allegato, mi lascia perplesso; infatti lo sviluppo dell’ambiente document rimette i codici di categoria al loro valore di default, quindi anche se \makeatletter cambia il \catcode di @ al valore 11 (letter), lo sviluppo rimette il \catcode di @ al valore 12 (other). Posso sbagliarmi, ma ho la sensazione che quel codice potrebbe funzionare se al posto di \global\@namedef ci fosse \expandafter\global\csname @namedef\endcsname. Ripeto: posso sbagliarmi.

            • #103350
              Up
              0
              Down
              ::

              Liverpool” post=103431Domanda secca: non c’è un modo per poter usare direttamente [tt]\colorlet[/tt] o un comando fornito da [tt]xcolor[/tt] all’interno del ciclo?

              Sicuramente ci sarà un qualche trucchetto che ti permette di farlo (xcolor mette a disposizione un sacco di comandi utili, molto spesso sconosciuti), ma al momento non lo vedo.

              Personalmente non vedo troppo macchinosa la soluzione con \@namedef e \@nameuse, ma dipende molto dal contesto vero e proprio con cui ti trovi di fronte. Se pensi di sviluppare un pacchetto per una soluzione generale, probabilmente opterei per questo perché lato utente (documento) hai una definzione per il colore molto pulita.

              Ciao
              Claudio

          Visualizzazione 5 filoni di risposte
          • Devi essere connesso per rispondere a questo topic.

          Go to top