Spiegazione disegno realizzato con TikZ

  • Creatore
    Topic
  • #82207
    Up
    0
    Down
    ::


    Ciao a tutti,

    navigando nel sito http://www.texample.net, ho notato questo disegno:
    `\documentclass{article}
    \usepackage[usenames,dvipsnames,pdftex]{xcolor}
    \usepackage{tikz,ifthen}
    \begin{document}
    \newcounter{density}
    \setcounter{density}{20}
    \begin{tikzpicture}
    \def\couleur{MidnightBlue}
    \path[coordinate] (0,0) coordinate(A)
    ++( 60:12cm) coordinate(B)
    ++(-60:12cm) coordinate(C);
    \draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
    \foreach \x in {1,…,15}{%
    \pgfmathsetcounter{density}{\thedensity+10}
    \setcounter{density}{\thedensity}
    \path[coordinate] coordinate(X) at (A){};
    \path[coordinate] (A) — (B) coordinate[pos=.15](A)
    — (C) coordinate[pos=.15](B)
    — (X) coordinate[pos=.15](C);
    \draw[fill=\couleur!\thedensity] (A)–(B)–(C)–cycle;
    }
    \end{tikzpicture}
    \end{document}
    % Name : RotateTriangle
    % Encoding : utf8
    % Engine : pdflatex
    % Author: Alain Matthes`
    Sulla base della mia conoscenza di [tt]TikZ[/tt] non riesco a spiegarmi questa cosa: nel ciclo [tt]\foreach,[/tt] la variabile [tt]\x[/tt] non viene usata; come mai? In questo caso, il ciclo [tt]\foreach[/tt] è un semplice escamotage per far ripetere la serie di comandi che contiene?

    Probabilmente è una sciocchezza, però mi piacerebbe avere l’opinione di chi ne sa ben più di me riguardo a [tt]TikZ.[/tt]

    Grazie e buona serata,
    Marco.

Visualizzazione 10 filoni di risposte
  • Autore
    Risposte
    • #82208
      admin
      Amministratore del forum
        Up
        0
        Down
        ::

        Marco87″ post=81540Ciao a tutti,

        navigando nel sito http://www.texample.net, ho notato questo disegno:
        `\documentclass{article}
        \usepackage[usenames,dvipsnames,pdftex]{xcolor}
        \usepackage{tikz,ifthen}
        \begin{document}
        \newcounter{density}
        \setcounter{density}{20}
        \begin{tikzpicture}
        \def\couleur{MidnightBlue}
        \path[coordinate] (0,0) coordinate(A)
        ++( 60:12cm) coordinate(B)
        ++(-60:12cm) coordinate(C);
        \draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
        \foreach \x in {1,…,15}{%
        \pgfmathsetcounter{density}{\thedensity+10}
        \setcounter{density}{\thedensity}
        \path[coordinate] coordinate(X) at (A){};
        \path[coordinate] (A) — (B) coordinate[pos=.15](A)
        — (C) coordinate[pos=.15](B)
        — (X) coordinate[pos=.15](C);
        \draw[fill=\couleur!\thedensity] (A)–(B)–(C)–cycle;
        }
        \end{tikzpicture}
        \end{document}
        % Name : RotateTriangle
        % Encoding : utf8
        % Engine : pdflatex
        % Author: Alain Matthes`
        Sulla base della mia conoscenza di [tt]TikZ[/tt] non riesco a spiegarmi questa cosa: nel ciclo [tt]\foreach,[/tt] la variabile [tt]\x[/tt] non viene usata; come mai? In questo caso, il ciclo [tt]\foreach[/tt] è un semplice escamotage per far ripetere la serie di comandi che contiene?

        Probabilmente è una sciocchezza, però mi piacerebbe avere l’opinione di chi ne sa ben più di me riguardo a [tt]TikZ.[/tt]

        Grazie e buona serata,
        Marco.

        Conosco Tikz molto meno di te, ma non lo chiamerei escamotage: è il classico ciclo (in questo caso for) per ripetere tot volte una serie di operazioni, come hai già osservato. Almeno credo.

        Ciao,
        Orlando

      • #82209
        Liverpool
        Partecipante
          Up
          0
          Down
          ::


          Se [tt]TikZ[/tt] avesse il costrutto [tt]while[/tt], sarebbe bastato qualcosa del tipo
          `\while \thedensity<171`Non essendoci il [tt]while[/tt] si è ricorsi al [tt]for[/tt] dichiarando una variabile che poi non viene effettivamente utilizzata.
          Un’altra scelta probabilmente più opportuna sarebbe stata
          `\foreach \x in {30,40,…,170}{%
          \pgfmathsetcounter{density}{\x}
          \path …`
          Ciao

        • #82210
          Up
          0
          Down
          ::


          Quel ciclo in effetti potrebbe essere riscritto in un altro modo (che spiego dopo). Come è stato fatto notare quel ciclo serve soltanto per aggiornare il valore di densità in modo consistente; ossia: `\pgfmathsetcounter{density}{\thedensity+10}
          \setcounter{density}{\thedensity}
          ` aggiunge 10 al valore corrente del contatore e successivamente setta il contatore con il nuovo valore. Il contatore inizialmente vale: `
          \setcounter{density}{20}
          ` quindi dopo il primo ciclo il suo valore sarà 30. Con questo trucchetto ad ogni successivo ciclo si mantiene il contatore aggiornato: `x=2 => \thedensity=40` Alla fine il valore di [tt]\thedensity[/tt] sarà 170 (puoi testarlo con [tt]\node

          at (0,0) {\thedensity};[/tt] fuori dal ciclo). Come fare per usare effettivamente la [tt]\x[/tt] nel ciclo? Con la chiave`evaluate=\x as \altro using formula` vedi pagina 507-508 del manuale. Quindi: `
          \foreach \x[evaluate=\x as \mydensity using int(\x*10+\thedensity)] in {1,…,15}{%

          \draw[fill=\couleur!\mydensity] (A)–(B)–(C)–cycle;
          }
          ` Uso [tt]int(formula)[/tt] solo per evitare che TikZ piazzi un [tt].0[/tt] finale ai valori che sarebbero interpretati come angolo dell’ancora (vedi http://tex.stackexchange.com/questions/94787/difference-between-newcommand-and-pgfmathsetmacro-used-in-tikz-coordinate).

          Allego un documento in cui si confrontano il metodo di Alain e l’uso di [tt]evaluate[/tt] (confrontando i valori finali dei contatori): `
          \documentclass{article}
          \usepackage[dvipsnames]{xcolor}
          \usepackage{tikz}
          \begin{document}
          \newcounter{density}
          \setcounter{density}{20}
          \begin{tikzpicture}
          \def\couleur{MidnightBlue}
          \path[coordinate] (0,0) coordinate(A)
          ++( 60:12cm) coordinate(B)
          ++(-60:12cm) coordinate(C);
          \draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
          \foreach \x[evaluate=\x as \mydensity using int(\x*10+\thedensity)] in {1,…,15}{%
          \path[coordinate] coordinate(X) at (A){};
          \path[coordinate] (A) — (B) coordinate[pos=.15](A)
          — (C) coordinate[pos=.15](B)
          — (X) coordinate[pos=.15](C);
          \draw[fill=\couleur!\mydensity] (A)–(B)–(C)–cycle;
          % test per vedere a quanto arriva mydensity
          \ifnum\x=15
          \node

          at (0,0){\mydensity};
          \fi
          }

          \end{tikzpicture}

          \begin{tikzpicture}
          \def\couleur{MidnightBlue}
          \path[coordinate] (0,0) coordinate(A)
          ++( 60:12cm) coordinate(B)
          ++(-60:12cm) coordinate(C);
          \draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
          \foreach \x in {1,…,15}{%
          \pgfmathsetcounter{density}{\thedensity+10}
          \setcounter{density}{\thedensity}
          \path[coordinate] coordinate(X) at (A){};
          \path[coordinate] (A) — (B) coordinate[pos=.15](A)
          — (C) coordinate[pos=.15](B)
          — (X) coordinate[pos=.15](C);
          \draw[fill=\couleur!\thedensity] (A)–(B)–(C)–cycle;
          }
          \node

          at (0,0) {\thedensity};
          \end{tikzpicture}
          \end{document}

          \end{document}
          % Name : RotateTriangle
          % Encoding : utf8
          % Engine : pdflatex
          % Author: Alain Matthes
          `

          Ciao
          Claudio

        • #82211
          Liverpool
          Partecipante
            Up
            0
            Down
            ::



            @cfiandra
            , ma qual è lo scopo di aggiornare il contatore, se fuori dal ciclo non viene più utilizzato?

          • #82212
            Up
            0
            Down
            ::

            Liverpool” post=81546 @cfiandra, ma qual è lo scopo di aggiornare il contatore, se fuori dal ciclo non viene più utilizzato?

            Il contatore serve “solo” in questo punto:`
            \draw[fill=\couleur!\mydensity] (A)–(B)–(C)–cycle;
            ` in cui in sostanza ad ogni ciclo rende il colore di sfondo progressivamente più scuro. Ad esempio:`
            \x=1 => fill=\couleur!30
            \x=3 => fill=\couleur!50

            \x=15 => fill=\couleur!170
            ` Nota che, appena fuori dal ciclo, c’è un iniziale:`\draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
            ` il cui valore di colore di sfondo è 20.

            Ciao
            Claudio

          • #82213
            Liverpool
            Partecipante
              Up
              0
              Down
              ::

              cfiandra” post=81548Il contatore serve “solo” in questo punto:

              Scusa: mi riferivo al codice di Alain. Ho capito.

              Grazie

            • #82214
              Up
              0
              Down
              ::


              Ciao,

              grazie a tutti per le vostre spiegazioni! Mi è sorto, però, un altro quesito: cosa succede dentro il ciclo? Se cerco [tt]coordinate[/tt][ [tt]pos[/tt] nel manuale di [tt]TikZ[/tt] non trovo nulla, e non capisco che cosa faccia.

              Grazie ancora e buona serata!
              Marco.

            • #82215
              Up
              0
              Down
              ::

              Marco87″ post=81557Mi è sorto, però, un altro quesito: cosa succede dentro il ciclo? Se cerco [tt]coordinate[/tt][ [tt]pos[/tt] nel manuale di [tt]TikZ[/tt] non trovo nulla, e non capisco che cosa faccia.

              Onestamente ci sono un sacco di cose non documentate in TikZ: prova a cercare la libreria [tt]3d[/tt] o la macro [tt]againpath[/tt], non le troverai. Ma esistono: `gedit $(kpsewhich tikzlibrary3d.code.tex) #Libreria 3d
              grep againpath $(kpsewhich tikz.code.tex) #Macro` In questo caso, però, trovi la sintassi a pagina 175:

              There is a special syntax for specifying “light-weighed” nodes:
              `\path . . . coordinate[ options ]( name )at( coordinate ) . . . ;`
              This has the same effect as
              `node[shape=coordinate][] options ]( name )at( coordinate ){},`
              where the at part might be missing.

              Serve per usare le coordinate che hanno un comportamento leggermente diverso dai nodi, vedi TikZ: difference between \node and \coordinate?

              Sostanzialmente, quello che fa il codice di Alain dentro il ciclo è questo:
              1) fissa la coordinata iniziale `\path[coordinate] coordinate(X) at (A){};` nota che se sostituisci con `\coordinate (X) at (A);` dovrebbe funzionare uguale;
              2) calcola un percorso che partendo dalla coordinata iniziale arrivi a [tt]0.15[/tt] di distanza rispetto alla coordinata successiva;
              3) itera aggiornando le posizioni delle coordinate, si vede da `(A) — (B) coordinate[pos=.15](A) % da A vado a 0.15 B e salvo la posizione in A `
              Puoi dedurre il comportamento facendo contrassegnare il primo giro fuori dal ciclo: `
              \documentclass{article}
              \usepackage[dvipsnames]{xcolor}
              \usepackage{tikz}
              \begin{document}
              \newcounter{density}
              \setcounter{density}{20}
              \begin{tikzpicture}
              \def\couleur{MidnightBlue}
              \path[coordinate] (0,0) coordinate(A)
              ++( 60:12cm) coordinate(B)
              ++(-60:12cm) coordinate(C);
              \draw[fill=\couleur!\thedensity] (A) — (B) — (C) — cycle;
              \path[red] (A) — (B) node[circle,draw,red,pos=.15]{x}
              — (C) node[circle,draw,red,pos=.15]{x}
              — (A) node[circle,draw,red,pos=.15]{x};
              \foreach \x[evaluate=\x as \mydensity using int(\x*10+\thedensity)] in {1,…,15}{%
              \path[coordinate] coordinate(X) at (A){};
              \path[coordinate] (A) — (B) coordinate[pos=.15](A)
              — (C) coordinate[pos=.15](B)
              — (X) coordinate[pos=.15](C);
              \draw[fill=\couleur!\mydensity] (A)–(B)–(C)–cycle;
              }

              \end{tikzpicture}
              \end{document}
              ` Risultato:

              [attachment=587]Senzanome_2013-01-23-2.jpg[/attachment]

              Ciao
              Claudio

              Attachments:
              You must be logged in to view attached files.
            • #82216
              Up
              0
              Down
              ::


              Ciao Claudio,

              chiedo scusa per non aver trovato da solo la spiegazione. Ti ringrazio molto della tua! 🙂 Mi mancava questa nozione:

              cfiandra`(A) — (B) coordinate[pos=.15](A) % da A vado a 0.15 B e salvo la posizione in A`

              Ora ho capito. Grazie ancora e buona serata!
              Marco.

            • #82217
              Up
              0
              Down
              ::

              Marco87″ post=81565chiedo scusa per non aver trovato da solo la spiegazione.

              Ma figurati. 🙂

              Quando sei in dubbio, fai come ho fatto io: prova a mettere qualche nodo per stampare i valori dei contatori o prova a colorare in modo diverso le parti di codice non chiare. È una specie di debug a mano a costo zero, ma funziona.

              Ciao
              Claudio

            • #82218
              Up
              0
              Down
              ::


              Ciao Claudio,

              cfiandra” post=81569

              chiedo scusa per non aver trovato da solo la spiegazione.

              Ma figurati. 🙂

              Quando sei in dubbio, fai come ho fatto io: prova a mettere qualche nodo per stampare i valori dei contatori o prova a colorare in modo diverso le parti di codice non chiare. È una specie di debug a mano a costo zero, ma funziona.

              Ciao
              Claudio

              Ottimo consiglio! 🙂 Lo applicherò sicuramente.

              Grazie e buona notte,
              Marco.

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

          Go to top