Creare un nuovo pattern con TikZ

  • Creatore
    Topic
  • #83539
    Up
    0
    Down
    ::


    Ciao a tutti,

    a causa della tesi sono alle prese con un disegno che vuole riprodurre un certo provino in calcestruzzo. Ho guardato sulla documentazione di [tt]TikZ[/tt] e, naturalmente, non esiste un pattern definito per questo. Quello che ho fatto io è stato di creare un “motivo” da ripetere mediante l’uso di [tt]\foreach[/tt] e poi da ritagliare con [tt]\clip,[/tt] in questo modo:
    `\documentclass{standalone}

    \usepackage{tikz}
    \usetikzlibrary{calc}

    \begin{document}

    \begin{tikzpicture}
    \clip (1.5,1.5) circle (1.5cm);

    \def\latoCls{1}
    \foreach \y in {0,…,3}
    \foreach \x in {0,…,3}
    {
    \fill [gray!35] ($(0,0)+(\x,\y)$) rectangle +(\latoCls,\latoCls);
    \fill [gray] ($(.25,.25)+(\x,\y)$) — +(.05,0) — +(-.025,.05);
    \fill [gray] ($(.25,.75)+(\x,\y)$) — ++(.03,-.06) — ++(.06,.09);
    \fill [gray] ($(.73,.55)+(\x,\y)$) — ++(.07,-.07) — ++(.07,.09);
    \fill [gray] ($(.125,.125)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.1,.48)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.115,.75)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.625,.125)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.5,.5)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.7,.81)+(\x,\y)$) circle (.21pt);
    \fill [gray] ($(.85,.24)+(\x,\y)$) circle (.21pt);
    }
    \end{tikzpicture}

    \end{document}`
    La mia domanda è: è possibile, invece di usare questo escamotage (anche poco elegante mi pare), definire un nuovo pattern? O è una cosa improponibile? Vi ringrazio per qualsiasi suggerimento abbiate da darmi.

    Grazie e buona giornata,
    Marco.

Visualizzazione 3 filoni di risposte
  • Autore
    Risposte
    • #83540
      Up
      0
      Down
      ::

      Marco87″ post=82879Ciao a tutti,

      a causa della tesi sono alle prese con un disegno che vuole riprodurre un certo provino in calcestruzzo. Ho guardato sulla documentazione di [tt]TikZ[/tt] e, naturalmente, non esiste un pattern definito per questo. Quello che ho fatto io è stato di creare un “motivo” da ripetere mediante l’uso di [tt]\foreach[/tt] e poi da ritagliare con [tt]\clip,[/tt] in questo modo:
      `\documentclass{standalone}

      \usepackage{tikz}
      \usetikzlibrary{calc}

      \begin{document}

      \begin{tikzpicture}
      \clip (1.5,1.5) circle (1.5cm);

      \def\latoCls{1}
      \foreach \y in {0,…,3}
      \foreach \x in {0,…,3}
      {
      \fill [gray!35] ($(0,0)+(\x,\y)$) rectangle +(\latoCls,\latoCls);
      \fill [gray] ($(.25,.25)+(\x,\y)$) — +(.05,0) — +(-.025,.05);
      \fill [gray] ($(.25,.75)+(\x,\y)$) — ++(.03,-.06) — ++(.06,.09);
      \fill [gray] ($(.73,.55)+(\x,\y)$) — ++(.07,-.07) — ++(.07,.09);
      \fill [gray] ($(.125,.125)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.1,.48)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.115,.75)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.625,.125)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.5,.5)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.7,.81)+(\x,\y)$) circle (.21pt);
      \fill [gray] ($(.85,.24)+(\x,\y)$) circle (.21pt);
      }
      \end{tikzpicture}

      \end{document}`
      La mia domanda è: è possibile, invece di usare questo escamotage (anche poco elegante mi pare), definire un nuovo pattern? O è una cosa improponibile? Vi ringrazio per qualsiasi suggerimento abbiate da darmi.

      Grazie e buona giornata,
      Marco.

      L’idea del nuovo pattern in se è buona, purtroppo però credo tu debba fare in modo di avere casualità nella generazione di cerchi e triangoli (impurità? non sono sicuro sia il termine tecnico però le chiamerò così lo stesso) e i pattern si comportano decisamente male con i numeri casuali (generalmente non ottieni mai il risultato voluto, al massimo inventi qualcosa di nuovo come il pattern tegole vedi qui 😀 ).

      Ecco che in casi come questi il buon [tt]path picture[/tt] toglie le castagne dal fuoco. Il discorso è che si vuole riempire lo sfondo di una qualsiasi forma e le impurità devono distribuirsi più o meno in modo casuale a prescindere se è un quadrato o un cerchio o chissà cosa. Con [tt]path picture[/tt] tutto ciò che viene disegnato non eccede mai il bordo ([tt]bounding box[/tt]) della forma ed, essendo un nodo, ha le solite ancore utili per caratterizzare il riempimento.

      Io ho pensato di:
      1) generare un certo numero di impurità (meno triangoli e più cerchi);
      2) posizionare ogni impurità in questo modo: a) generando due numeri casuali compresi fra 0 e 1 come offset b) generando due numeri casuali compresi fra -1 e 1 come coefficiente, c) definire la posizione x,y come somma fra il centro della bounding box e il prodotto fra offset e coefficiente (per il termine x ho ancora moltiplicato per 2 – spiego bene dopo perché).

      Il codice: `
      \documentclass{standalone}

      \usepackage{tikz}
      \usetikzlibrary{calc}

      \begin{document}

      \tikzset{calcestruzzo/.style={
      path picture={
      \foreach \trignum in {1,…,10}{
      \pgfmathrnd
      \pgfmathsetmacro\xoff\pgfmathresult
      \pgfmathrnd
      \pgfmathsetmacro\yoff\pgfmathresult
      \pgfmathrand
      \pgfmathsetmacro\xcoeff\pgfmathresult
      \pgfmathrand
      \pgfmathsetmacro\ycoeff\pgfmathresult
      \fill [gray] ($(2*\xoff*\xcoeff,\yoff*\ycoeff)+(path picture bounding box.center)$)
      — +(.05,0) — +(-.025,.05);
      }
      \foreach \circlenum in {1,…,25}{
      \pgfmathrnd
      \pgfmathsetmacro\xoff\pgfmathresult
      \pgfmathrnd
      \pgfmathsetmacro\yoff\pgfmathresult
      \pgfmathrand
      \pgfmathsetmacro\xcoeff\pgfmathresult
      \pgfmathrand
      \pgfmathsetmacro\ycoeff\pgfmathresult
      \fill [gray] ($(2*\xoff*\xcoeff,\yoff*\ycoeff)+(path picture bounding box.center)$)
      circle (.21pt);
      }
      }
      }
      }
      \begin{tikzpicture}
      \fill[gray!35,calcestruzzo] (0,0) circle (0.5cm);
      \fill[gray!35,calcestruzzo] (0,1)–(3,2)–(4,0.75)–cycle;
      \fill[gray!35,calcestruzzo] (1,0)–(3,-0.5)[rounded corners=2pt]–(4,0.5)–(2,0.65)–cycle;
      \end{tikzpicture}
      \end{document}
      ` Il risultato:

      [attachment=622]pr_2013-03-12.jpg[/attachment]

      A questo punto si noti che in realtà non è che tutti i cerchi e triangoli appaiano effettivamente nel riempimento, di qualsiasi forma: ciò è dovuto al fatto che il numero casuale generato probabilmente è troppo alto e viene “tagliato”. Se si eliminasse il 2* ciò non accadrebbe più, ma tutte le impurità sarebbero troppo concentrate non dando assolutamente l’idea giusta. Chiaramente il discorso cambia ad ogni minuto di compilazione: PGF ha un seed basato su \time*\year perciò ad ogni minuto i numeri casuali differiscono e quindi le impurità cambiano posizione.

      P.S. Lascio a chi vuole la possibilità di migliorare il codice creando apposite chiavi per personalizzare almeno: a) numero di impurità (una chiave per tipo), b) il colore dell’impurità.

      EDIT: c’era un errore grave che ho corretto. Gli offsets sono generati con numeri casuali fra ([tt]\pgfmathrand[/tt]) -1 e 1 perché in questo modo nella forma possono ricoprire l’intera area (se fosse stato fra 0 e 1 gli aggregati (grazie Marco per la correzione 🙂 ) si sarebbero disposti solo nel “quadrante positivo”).

      Ciao
      Claudio

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


      Ciao Claudio,

      intanto grazie mille! Anche stavolta m’hai insegnato qualcosa di nuovo di [tt]TikZ.[/tt] Quelle che hai definito “impurità” in realtà sono gli aggregati presenti nel calcestruzzo (sabbia, ghiaia, …), ma il risultato che hai ottenuto è comunque proprio quello a cui pensavo! Il tuo codice è molto interessante e ora lo guardo per bene (grazie delle spiegazioni esaustive che hai dato).

      Grazie ancora e buona giornata!
      Marco.

    • #83542
      Up
      0
      Down
      ::


      Marco,

      nota che ho corretto un errore nel precedente messaggio.

      Ciao
      Claudio

    • #83543
      Up
      0
      Down
      ::


      Ciao Claudio,

      grazie mille!

      Buona serata,
      Marco.

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

Go to top