Algoritmi Generativi
Transcription
Algoritmi Generativi
1 ALGORITMI GENERATIVI con GRASSHOPPER ZUBIN KHABAZI Edizione Italiana a cura di Antonino Marsala, www.mandarinoblu.com [email protected] © 2010 Zubin Mohamad Khabazi Questo libro è prodotto e pubblicato in formato digitale per uso pubblico. Non è consentita la riproduzione totale o parziale senza il permesso dell'autore, eccetto per le revisioni. Per vedere gli ultimi aggiornamenti o in caso di chiarimenti, visitate il mio sito web, www.MORPHOGENESISM.com [email protected] 2 Introduzione Avete mai giocato con il LEGO Mindstorms NXT robotic set? Bene, la modellazione associativa è qualcosa del genere. Se tutto inizia a diventare algoritmico e parametrico, perchè non anche l'architettura? Durante il mio master "Emergent Technologies and Design (EmTech)" presso l'Architectural Association (AA), ho deciso di condividere l'esperienza nell'ambito degli Algoritmi Generativi e nella modellazione parametrico-associativa con Grasshopper, che trovo essere una piattaforma molto potente per questo tipo di progettazione. In questa seconda edizione, così come ho modificato il nome da "Modellazione Algotmica" a "Algoritmi Generativi", ho provato ad aggiornare alcuni esperimenti e temi viste le modifiche che sono state apportate al progetto di Grasshopper, ancora in evoluzione. Spero che questi tutorial vi possano aiutare per capire meglio Grasshopper e gli algoritmi generativi. Mi sarebbe piaciuto aggiornarli, ma bisogna considerare che la maggior parte degli esperimenti e degli esempi sono stati fatti su una versione precedente del plug-in, quindi se trovate delle differenze potrebbe dipendere da questo. Credo che il libro necessiti di revisioni editoriali, visto però che si tratta di un un prodotto non-profit e non commerciale, vi prego di perdonarmi per questa mancanza. Sono molto soddifatto dal fatto che, da quando ho pubblicato questo libro, ho trovato grandi amici in tutto il mondo. Consideratevi dunque liberi di contattarmi per ogni richiesta e spiegazioni tecniche. Buon lavoro e buona fortuna! Ringraziamenti Prima di tutto vorrei ringraziare Bob McNeel per il suo aiuto conGrasshoper3D e David Rutten per l'ispirazione, oltre che per il suo supporto. Sono anche felice di rigrazione i direttori del AA/EmTech e i tutor, Mike Weinstock, Michael Hensel, oltre che Achim Menges che ha verificato i miei concetti parametrici e computazionali. Ancora un ringraziamento per Stylianos Dritsas (AA/KPF) , Dr.Toni Kotnik (AA/ETH) per i loro corsi di calcolo, scripting e geometria avanzata. Sono estremamente grato agli studenti, architetti e progettisi che mi hanno contattato e hanno condiviso le loro conoscenze e mi hanno fatto notare gli errori presenti. Zubin M Khabazi Marzo 2010 Nota del traduttore Innanzitutto vorrei ringraziare Zubin Khabazi per aver prima condiviso questo testo, e poi per aver accettato la mia proposta di collaborazione. Durante i miei anni di lavoro con Rhinoceros ho appreso tanto da chi, come Zubin, ha messo a disposizione le proprie esperienze e conoscenze che mi hanno permesso non solo di utilizzare il programma, ma anche di capire cosa c'è dietro ogni singola scelta, in modo da insegnarlo e trasmetterlo ai miei studenti. Ho cercato di essere più fedele possibile al testo originale aggiornandolo dalla versione 0.6 (sulla quale è stata fatta le seconda edizione) all'attuale 0.8. . Come dice lo stesso autore per la versione originale, anche la traduzione necessiterebbe di una revisione editoriale più accorta. Abbiamo però preferito anche qui privilegiare la pubblicazione, lasciandoci aperta la possibilità di raffinare la scorrevolezza del testo. Invito quindi tutti coloro che hanno dei suggerimenti o dei dubbi a contattarmi per spiegare meglio alcuni passaggi che potrebbero non risultare completamente chiari. Antonino Marsala – Febbraio 2011 3 Contenuti Capitolo_1_AlgoritmiGenerativi 1_1_Algoritmi Generativi ......................................................................6 ..............................................................................................................6 Capitolo_2_L'inizio ......................................................................9 2_1_ Metodo ................................................................................................10 2_2_Conoscenze di base ................................................................................................10 2_2_1_Interfaccia, area di lavoro ................................................................................................10 2_2_2_Componenti ................................................................................................10 2_2_3_Combinazione di dati ….............................................................................................18 2_2_4_Help per i componenti (menù contestuale) .............................................................20 2_2_5_ Ricerca e aggiunta di un componente tramite tastiera …...................................................20 Capitolo_3_Insiemi di dati e Matematica …..........................................................21 3_1_Insiemi di dati numerici 3_2_Punti e griglie di punti 3_3_Altri insiemi numerici 3_4_Funzioni 3_5_Dati Booleani 3_6_Cull list 3_7_Liste di dati 3_8_Pattern per geometrie planari ...............................................................................................22 ...............................................................................................24 ...............................................................................................26 ...............................................................................................28 ...............................................................................................31 ...............................................................................................32 ...............................................................................................34 ...............................................................................................38 Capitolo_4_Trasformazioni …......…..................................................................50 4_1_Vettori e Piani ................................................................................................51 4_2_Curve e geometrie lineari ................................................................................................52 4_3_Esperimento combinato: Swiss Re ....................................................................................58 4_4_Attrattori ................................................................................................66 Capitolo_5_Spazio Parametrico …......…........................................................76 5_1_Spazio parametrica monodimensionale ........................................................................77 5_2_Spazio parametrico bidimensionale ....................................................................................78 5_3_Transizioni tra gli spazi ................................................................................................79 5_4_Componenti parametrici di base ....................................................................................80 5_4_1_Valutazione di curve ................................................................................................80 5_4_2_Valutazione di superfici ................................................................................................81 5_4_3_Punto più vicino alla curva e alla superficie .............................................................83 5_5_Proliferazione di oggetti nello spazio parametrico .............................................................83 5_6_Alberi di dati ................................................................................................91 Capitolo 6_Deformazioni e morphing 6_1_Deformazioni e moprhing 6_2_Pannellizzazione 4 …......….............................................100 ..............................................................................................101 ..............................................................................................103 6_3_Manipolazioni di micro livello ..............................................................................................106 6_4_Modulazione reattiva ..............................................................................................109 Capitolo_7_Superfici NURBS e Mesh …......…......................................................116 7_1_Superfici NURBS parametriche ..............................................................................................117 7_2_Geometria e Topologia ..............................................................................................124 7_3_Mesh ..............................................................................................125 7_4_Analisi cromatica ..............................................................................................134 7_5_Manipolazione delle mesh come metodo progettuale ...............................................137 Capitolo_8_Fabbricazione …................…......................................................140 8_1_Datasheet ..............................................................................................141 8_2_Tagli laser e manifatturazione basata sul taglio ...........................................................152 Capitolo_9_Strategia di design Bibliografia 5 …...............................................................167 …......…................................................................171 1_1_ Algoritmi Generativi Se guardiamo all'architettura come ad un oggetto rappresentato nello spazio, per comprenderlo appieno e per progettarlo, dobbiamo sempre ragionare con la geometria e un po' di matematica. Nella storia dell'architettura, diversi stili architettonici hanno presentato diverse tipologie di geometria e logiche di articolazione, e ogni periodo ha trovato un modo di dialogare con le sue problematiche e le sue domande inerenti la geometria. Da quando i computer hanno iniziato ad aiutare gli architetti, simulando lo spazio e le articolazioni geometriche, questi sono diventati uno strumento integrante del processo progettuale. La Geometria computazionale è divenuta un'interessante materia di studio e la combinazione di programmazione algoritmica con la geometria, ha prodotto delle geometrie algoritmiche note come Algoritmi Generativi. Sebbene gli applicativi 3D abbiano aiutato a simulare parte di ogni spazio visualizzato, è stata la nozione di Algoritmo Generativo che ha portato le attuali possibilità di progettazione, come la “progettazione parametrica”, nel regno dell'architettura. Gli Architetti hanno iniziato ad usare curve free form e superfici per disegnare e progettare gli spazi andando oltre le limitazioni della geometria convenzionale dello “spazio euclideo”. E' stata una combinazione tra Architettura e Digitale che ha portato “i blob” alla ribalta, facendoli ulteriormente progredire. Nonostante la crescita del calcolo sia estremamente veloce, l'architettura ha provato a tenere il passo di questo veloce ritmo digitale. Dopo l'era del “blob”, l'architettura contemporanea sembra essere più chiara riguardo a questo argomento. La progettazione architettonica è stata influenzata dalle potenzialità delle geometrie algoritmiche computazionali, con gerarchie multiple e alto livello di complessità. Progettare e modellare superfici free form e curve come se fossero elementi di costruzioni associati con diversi componenti e aventi pattern multipli, non è un lavoro facile da portare avanti con metodi tradizionali. La potenza degli algoritmi e degli script che spostano in alto l'asticella della progettazione, è proprio questa. E' ovvio che anche solo per pensare a geometrie complesse abbiamo bisogno di strumenti appropriati, specialmente applicativi capaci di simulare le geometrie e controllarne le proprietà. Come risultato, gli architetti sono interessati ora ad usare Swarms, Cellular Automata o Genetic Algorithms per creare progetti algoritmici ed andare oltre gli attuali limiti di forme e spazio. All'orizzonte si profila un catalogo pieno di complessità e molteplicità che combina insieme creatività e ambizione. Fig.1.1 Modellazione parametrica per “Evolutionary Computation and Genetic Algorithm, Zubin Mohamad khabazi, Emergence Seminar, AA” tenuto da Michael Weinstock , Autunno 2008 Facendo un passo avanti, ora sembra possibile incorporare le proprietà dei sistemi materiali in una progettazione algoritmica con il concetto parametrico. Guardando agli effetti materiali e alle loro 6 reazioni all'ambiente ospitante nella fase progettuale, ora la innate potenzialità dei componenti e dei sistemi possono essere applicate ai modelli parametrici per la progettazione. Non solo questi algoritmi generativi dialogano con la generazione della forma, ma palesano anche un grande potenziale per incorporare la logica dei materiali. “La logica di base della progettazione parametrica, può essere qui strumentalizzata come un metodo progettuale alternativo, uno in cui il rigore geometrico della modellazione parametrica può essere distribuito prima per integrare i vincoli della manifattura, le logiche del montaggio e le caratteristiche del materiale nella definizione di semplici componenti, e poi per la riproduzione dei componenti dentro costruzioni e sistemi più grandi. Questo approccio impiega l'esplorazione di variabili parametriche per capire il comportamento di un tipo di sistema e quindi usa queste conoscenza per studiare una strategia di risposta al sistema per le condizioni ambientali e le forze esterne” (Hensel, Menges, 2008) Per lavorare con oggetti complessi, il processo progettuale parte da un primo semplice livello, a cui vengono aggiunti nuovi strati; le forme complesse sono composte da gerarchie differenti, ognuna associata con la propria logica e propri dettagli. Questi livelli sono anche tra loro interconnessi, e i loro membri influiscono l'uno con l'altro. In questo senso questo metodo viene definito “associativo”. In generale, la modellazione associativa si riferisce ad un metodo in cui gli elementi progettuali sono costruiti gradualmente in gerarchi multiple e ad ogni livello, alcuni parametri di questi elementi sono estratti per generare altri elementi in un altro livello e questo procedimento va avanti, passo dopo passo per produrre la geometria complessiva. Quindi il punto estremo di una curva può esser il centro di una circonferenza: ogni cambiamento nella curva comporta un cambiamento associato della circonferenza. Fondamentalmente questo metodo di progettazione dialoga con una grande quantità di dati e di calcoli e avviene attraverso il flusso degli algoritmi. Una cosa fondamentale è che tutte queste geometrie sono facilmente regolabili dopo il processo. I progettisti hanno sempre accesso agli elementi di design del prodotto, dal punto di partenza fino ai dettagli. Effettivamente, poiché il design del prodotto è frutto di un algoritmo, gli input dell'algoritmo possono essere modificati e il risultato può essere aggiornato di conseguenza. E ora dunque possibile fare uno schizzo digitale di un modello e generare centinaia di variazioni, regolando i più semplici parametri geometrici. E' inoltre possibile incorporare le proprietà dei sistemi materiali, i vincoli di fabbricazione e le logiche di assemblaggio in parametri. E' inoltre possibile rispondere all'ambiente ed essere associativi in senso largo. “ … il design parametrico permette il riconoscimento dei modelli del comportamento geometrico, e la relativa capacità performativa e le tendenze del sistema. In un riscontro continuo con l'ambiente esterno, queste tendenze comportamentali possono quindi informare lo sviluppo ontogenetico di uno specifico sistema attraverso la differenziazione parametrica dei sottogruppi” (Hensel, Menges, 2008). 7 Fig.1.2.Ricerca nel campo delle membrane e delle superfici minime, modello fisico, Movimento di membrane di B. modellate con Grasshopper Zubin Mohamad Khabazi, EmTech Core-Studio, AA, tenuto da Michael Hensel and Achim Menges, Autunno 2008 Grasshopper è una piattaforma che attraverso Rhinoceros permette di rapportarsi con gli algoritmi generativi e le tecniche di modellazione associativa. I prossimi capitoli sono pensati per combinare le tematiche geometriche con gli algoritmi per indirizzare alcune problematiche progettuali architettoniche verso un metodo 'Algoritmico'. Gli esempi sono pensati allo scopo di allargare la tematica della geometria e di usare più comandi possibile. 8 CAPITOLO_2_L'inizio 9 2_1_Metodo Questa nuova edizione del precedente “Modellazione Algoritmica” chiamato ora “Algoritmi generativi” è stata fatta grazie alle richieste dei miei amici di Grasshopper sparsi per il mondo, in conseguenza ai cambiamenti che sono stati fatti al plugin. Visto che Grasshopper è un progetto in evoluzione che viene modificato e integrato in maniera veloce, mi è sembrato necessario aggiornare il libro in questo momento (e non sono totalmente convinto che nel momento in cui lo leggerete, non saranno necessari nuovi aggiornamenti). Considerate che la maggior parte degli esperimenti sono stati fatti con una versione precedente del plugin, ma ho provato ad aggiornarli dove necessario e sono convito che se troverete qualche differenza, non sarà troppo difficile andare avanti da soli. L'obiettivo principe del libro è quello di focalizzare l'attenzione su alcune problematiche geometriche e architettoniche, sui progetti, e sullo sviluppo della comprensione degli algoritmi generativi e della modellazione parametrica, basata su esperimenti progettuali invece che su di una descrizione di tipo matematica o geometrica. Per fare ciò, nella maggiora parte dei casi, presumerò che voi conosciate gli ingredienti di base della discussione e non entrerò nella definizione di grado della curva, se non in alcuni casi in cui lo riterrò necessario. Grasshopper cresce velocemente e sta diventato una piattaforma adeguata per la progettazione di architetture. Più che uno strumento o un applicativo, presenta un modo di pensare la progettazione, un metodo chiamato parametrico, o associativo. Questo metodo di sta sviluppando attraverso gli utenti di tutto il mondo come un esempio pratico di intelligenza distribuita. Poichè questi sviluppi di metodi avvengono costantemente, e ci sono sempre aggiornamenti nel software, oltre che discussioni interessanti, ti consiglio di controllare la pagina di Grasshopper. In ogni caso in questo capitolo vorrei discutere brevemente le problematiche generali dell'area di lavoro e le basi di ciò che dovremo conoscere quello che dovremo conoscere in anticipo. http://www.Grasshopper3d.com/ 2_2_Conoscenze di base 2_2_1_Interfaccia , area di lavoro Accanto ai menu tipici di Windows, ci sono altri due parti importanti nell'interfaccia di Grasshopper: il pannello dei componenti e il Canvas. Il pannello dei componenti fornisce tutti gli elementi di cui necessitiamo per i nostri progetti, mentre il Canvas rappresenta l'area di lavoro dove inserire i componenti e impostare i nostri algoritmi. Potete cliccare su qualunque oggetto dai pannelli e cliccare ancora sul canvas per portarli nell'area di lavoro, oppure trascinarli. Le altri zone 10 dell'interfaccia sono facili da esplorare e diventeranno familiari con l'utilizzo. Maggiori informazioni potrete trovarle qui http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryPluginInterfaceExplained.html Fig.2.1. Pannello dei componenti e Canvas 2_2_2_Componenti In Grasshopper vi sono diversi tipi di oggetti, pannelli e componenti, menu che useremo per progettare. Li potrai trovare sotto dieci differenti tabelle chiamate: Params, Math, Sets, Vector, Curve, Surface, Mesh, Intersect, XForm Ogni scheda contiene diversi pannelli e altrettanti oggetti. I comandi sono ordinati all'interno di questi pannelli. Ci sono oggetti che disegnano geometrie quali linee, cerchi e ci sono inoltre diversi comandi per spostare, scalare, dividere e deformare queste geometrie. Quindi alcuni oggetti disegnano e generano dati, alcuni modificano geometrie o dati esistenti. I parametri sono oggetti che rappresentato i dati come un punto o una linea. Li potete disegnare dai parametri attinenti o li potete definire manualmente da un oggetto disegnato direttamente su 11 Rhinoceros. I componenti sono invece oggetti che fanno qualcosa, come muovere, orientare o scomporre. Solitamente abbiamo bisogno di provvedere a recuperare i dati pertinenti per farli funzionare. Come ho già detto, ad ogni funzione corrisponde un oggetto che può essere portato sul canvas. In questo manuale userò il termine componente per parlare di ogni oggetto presente nel pannello dei componenti per semplificare le cose. Userò la dicitura <> per nominarli, in modo che sia facile individuarli nel testo. Per esempio per indicare il componente che genera un punto, usero <point>. Componente <point> (punto) Cliccando con il tasto destro su un componente, apparirà un menu che contiene alcuni aspetti di base: questo menu è chiamato “menu contestuale” Menu contestuale Da ora in poi dovrete trovare i componenti giusti dai pannelli ed impostare le connessione tra questi componenti per poter generare il vostro algoritmo progettuale, in modo da vedere i risultati nell'area di lavoro di Rhinoceros. Se lo scripting rappresentauna versione astratta e codificata degli algoritmi, con Grasshopper, il canvas diventa luogo di rappresentazione visuale degli algoritmi, come un diagramma di flusso che tra le mani del progettista risulta più sensibile e flessibile. 12 Fig.2.2 Diagramma di flusso vs Algoritmo di Grasshopper Definizione delle geometrie esterne La maggior parte delle volte, partiremo con l'importazione sul canvas di Grasshopper di oggetti disegnati su Rhino. Potrà trattarsi di un punto, una curva o una superficie fino ad oggetti multipli e complessi. Significa che potremo usare i nostri oggetti creati manualmente, oppure oggetti generati tramite script da Rhinoceros su Grasshopper come sorgente esterna. Poiché ogni geometria di Grasshopper necessita di un componente nel canvas per poterci lavorare, dobbiamo definire le nostre geometrie esterne nel canvas attraverso i giusti componenti. Per questa motivo possiamo guardare nella scheda Params, nel pannello Geometry. C'è una lista di diverse tipi di geometrie che potete usare per definire un oggetto esterno dall'area di lavoro di Rhinoceros. Dopo aver portato il componente geometrico appropriato, definiamo l'oggetto di rhino cliccando con il tasto destro sul componente e scegliendo “set one.../set multiple...” (imposta un..../imposta multipli.....) per assegnare gli oggetti ai componenti. Ora avete bisogno di selezionare la vostra geometria su Rhinoceros. Importando uno o più oggetti con un componente, questi diventano oggetti di Grasshopper e possono ora essere usati per ogni scopo. Fig.2.3 I diversi tipi di geometria in Params>Geometry 13 Facciamo un semplice esempio Abbiamo tre punti nella finestra di Rhinoceros e vogliamo disegnare un triangolo passante per questi tre punti in Grasshopper. Come prima cosa dobbiamo importare questi punti in Grasshopper. Abbiamo bisogno di tre componenti <point> che possiamo trovare in Params>Geometry>Point e per ognuno possiamo andare sul menu contestuale (tasto destro) e selezionare 'set one point' (imposta un punto) e quindi selezione il punto dalla finestra di rhino. (Fig. 2.4) Fig.2.4. Impostare il punto da Rhinoceros attraverso un componente di Grasshopper Fig. 2.5. Il canvas di Grasshopper e i tre punti definiti che diventano delle croci (x) rosse nella finestra di rhino. Ho rinominato i componenti con il nome Point A/B/C tramite la prima voce del menu contestuale, in modo da riconoscerli facilmente sul canvas. 14 Connessione di componenti Ci sono diverse azioni che possiamo applicare ai componenti. Generalmente un componente prende dei dati da una o da più sorgenti e restituisce dei risultati. Abbiamo bisogno di connettere dei componenti che includano i dati in ingresso verso dei componenti che li processino e collegare a loro volta i risultati ad altri componenti che necessitano di questi risultati e così via. Tornando all'esempio, se andiamo nella scheda delle Curve, nel pannello Primitive, troverete il componente <line>. Portatelo sul canvas. Connettete quindi <point A> all'ingresso A di <line> e <point B> all'ingresso B (per connettere i componenti, cliccate semplicemente sul semicerchio nella parte destra di <point> e trascinatalo verso l'altro semicerchio sul componente destinazione (l'ingresso A/B di <line>). A queste punto vederete che Rhinoceros ha disegnato una linea tra i due punti. Fig.2.6 Connessione del componente <point> al componente <line> trascinando dall'uscita del <point B> all'ingresso di <line>. Ora aggiungete un altro componente <line> per il <point B> e <point C>. Stessa cosa tra <point C> e <point A> con il terzo componente <line>. Eh si! C'è un triangolo nella finestra di Rhino. Fig. 2.7. Componente <line> disegnato tra due componenti <point>. Come vedete ogni componente può essere usato più di una volta come sorgente di informazione per altre azioni 15 Fig. 2.8 Se ora cambiate manualmente la posizione dei punti direttamente su Rhino, la posizione dei punti su Grasshopper (quelli con la X) e il triangolo risultante verranno modificati di conseguenza, ma le linee tra i punti (il triangolo) rimarranno e si aggiorneranno. Come vedete in questo primo esempio, la tecnica associativa rende possibile manipolare i punti, mantenendo la geometria del triangolo fatto di punti senza che siano necessarie ulteriori modifiche. L'idea è quindi di preparare gli oggetti ('alimentare' gli input degli algoritmi), impostare le relazioni tra gli oggetti e aggiungere altre manipolazioni (le funzioni degli algoritmi) e generare il progetto (risultato dell'algoritmo). Lavoreremo ancora su questo concetto per sviluppare la comprensione degli algoritmi. Input/Output Come già detto, ogni componente di Grasshopper ha dei connettori in ingresso (input) e in uscita (output), il che significa che il componente processa i dati in ingresso e li restituisce in uscita. La porta di Input si trova sulla parte sinistra del componente, mentre quella di output si trova a destra. I dati arrivano da ogni sorgente collegata alla sezione Input del componente e in Output abbiamo il risultato che il componente genera attraverso una specifica funzione. Per saperne di più (testo in inglese) http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryVolatileDataInheritance.html E' sempre necessario sapere di che tipo di input avete bisogno per quella specifica funzione e cosa si otterrà dopo il processo. Parleremo ancora in seguito dei diversi tipi di dati che dovremo procurarci. Per avere maggiori spiegazioni, vi suggerisco di tenere il mouse sopra ogni connettore in ingresso o uscita: apparirà una nota in cui potrete leggere il nome, il tipo di dato necessario, se è stato impostato un valore predefinito o no, e soprattutto la funzione del componente. Fig.2.9 Lasciando il puntatore del mouse sopra il connettore input/output del componente appare una finestra di suggerimento. 16 Connessioni Multiple A volte è necessario connettere ad un componente più di una sorgente di dati. Immaginate, nell'esempio seguente, di voler tracciare due linee dal <point A> al <point B> e poi per il <point C>. Potete usare due diversi componenti <line> oppure usare un componente <line> connettendo entrambi il punto B e il punto C alla lettera B del componente <line>. Per fare ciò, è necessario premere il tasto Shift nel momento in cui si connette la seconda sorgente di dati al componente. Senza questo accorgimento Grasshopper sostituirà il secondo connettore al primo. Quando si preme Shift, sul puntatore appare una circonferenza verde con una piccola icona (+) che normalmente è grigia. Potete anche usare Ctrl per disconnettere un componente da un altro (normalmente è possibile farlo anche usando il menu contestuale). In questo caso la circonferenza attorno al puntato verrà mostrata in rosso con una piccola icona (-) Fig. 2.10 Connessione multipla per un componente usando il tasto Shift Il codice dei colori Su Grasshopper esiste un sistema di codici dei colori il cui scopo è mostrare lo “stato” del componente. Fig. 2.11 Il codice dei colori Un componente di colore grigio indica che non ci sono problemi e il tipo di dato definito è giusto o comunque il componente lavora in maniera corretta. L'arancio indica invece che dobbiamo fare attenzione! C'è almeno un problema che dove essere risolto affinchè il componente continui a funzionare. Il componente rosso indica una errore e non può funzionare in questa situazione. La sorgente di errore deve essere scoperta e risolta per consentirne l'utilizzo. Potrete trovare un primo aiuto riguardante l'errore nel menu contestuale del componente (menu contestuale> Runtime warning/error) e quindi controllare i dati in ingresso per capire il motivo del problema. Il colore verde significa invece che il componente è selezionato. La geometria associata al 17 componente stesso diventa anch'essa verde nella finestra di Rhinoceros (mentre tutte le geometrie predefinite su Grasshopper sono rosse). Anteprima Tutti i componenti che producono un oggetto in Rhinoceroshanno un'opzione di visualizzazione di anteprima nel proprio menu. La possiamo usare per nascondere o mostrare le geometrie nell'area di lavoro. Ogni anteprima non selezionata (output nascosto) fa si che il nome del componente diventi retinato. Solitamente usiamo l'opzione di anteprima per nascondere geometrie non desiderate, quali punti di base e le linee in modelli complessi, per evitare distrazioni. Questa opzione, in modelli complessi, consente di processare i dati in maniera più veloce, perciò è meglio nascondere le geometrie di base quando non è necessario vederle. 2_2_3_ Combinazione di dati Per tanti componenti di Grasshopper, è sempre possibile indicare una lista di dati anziché un solo input. Si tratta, in pratica, di creare una lista di punti, per esempio, e connetterli ad un componente <line> per rappresentare più linee contemporaneamente anziché una sola. Procurandoci le informazioni necessarie sarà dunque possibile disegnare centinaia di oggetti partendo da un solo componente. Guardiamo il seguente esempio: Ho due diversi insiemi, ognuno dei quali contenente sette punti. Ho usato due componenti <point> e ho impostato 'set multiple point' (imposta punti multipli) per immettere tutti i punti più alti in un gruppo e tutti i quelli più bassi nell'altro. Come vedete, connettendo questi due gruppi di punti ad un componente <line>, vengono generate sette linee passanti per i punti. Possiamo quindi generare più di un oggetto da ciascun componente. (fig. 2.12) Fig.2.12 Impostazione di punti multipli tramite i quali vengono generate delle linee Ma cosa potrebbe succedere se nei due insiemi il numero di punti non è lo stesso ? Nell'esempio che segue, ho sette punti nella riga superiore e dieci in quella inferiore. Abbiamo dunque bisogno dunque di introdurre il concetto di amministrazione dei dati in Grasshopper, chiamato combinazione (o incrocio) dei dati. Se date un'occhiata al menu contestuale del componente, potrete vedere che ci sono tre opzioni chiamate 18 Shortest list (lista più corta) Longest list (lista più lunga) Cross Reference (riferimento incrociato) Date un'occhiata alle differenze mostrate in figura 2.13 E' evidente che shortest list produrrà come risultato una serie di linee pari al numero dei dati della lista più corta, mentre la longest list creerà un numero di linee pari al numero di dati presenti nella lista più lunga, combinando l'ultimo valore della lista più corta più di una volta. L'opzione Cross Reference connette tutti i punti secondo tutte le possibili combinazioni. E' un'opzione ad alto consumo di memoria e qualche volte è possibile sia necessario un po' di tempo perchè la scena venga aggiornata. Visto che le immagini sono chiare, mi fermo qui con la descrizione. Per maggiori informazioni consultate il seguente link (testo in inglese) http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryDataStreamMatchingAlgorithms.html Fig. 2.13 combinazione di dati A: shortes list, B: longest list e C: cross reference 19 2_2_4 Help per i componenti (menù contestuale) Considerando che non è utile spiegare tutti i componenti, la cosa migliore è quella di provarli e capire come usarli gradualmente durante gli esperimenti. Suggerisco dunque di giocarci, scegliere un componente, andare sul menu contestuale dello stesso (tasto destro) e leggere l'Help che sarà di grande aiuto per capire come questo funzioni, quale tipo di dati siano necessario e che tipo di dati in uscita produce. Ci sono altre utili caratteristiche nel menu che vedremo più avanti. Fig. 2.14 Menu contestuale e parte relativa all'Help del componente 2_2_5 Ricerca e aggiunta di un componete tramite tastiera Per trovare rapidamente un componente di cui conosciamo il nome, anziché perdere tempo all'interno delle schede dei componenti, è possibile fare doppio click sul canvas e scrivere il nome del componente stesso per portarlo nell'area di lavoro. Per coloro che sono soliti usare la tastiera per lavorare, questo potrebbe essere un bel trucco. Fig. 2.15 Ricerca del componente <line> nel menu contestuale. Per attivarlo è necessario fare doppio click sul canvas, e digitare il nome. Il componente verrà in questo modo portato nell'area di lavoro. 20 CAPITOLO_3_ Insiemi di dati e Matematica 21 Capitolo_3_ Insiemi di dati e Matematica Sebbene negli applicativi per il 3D possiamo selezionare le geometrie dai menu e disegnarle in maniera esplicita senza pensare agli aspetti matematici che stanno dietro, per poter lavorare con gli algoritmi generativi, come suggerisce il nome, dobbiamo pensare ai dati e alla matematica per creare dei valori in entrata per alimentare l'algoritmo e generare oggetti. Poiché non vogliamo disegnare tutto a mano, abbiamo bisogno di alcune sorgenti di dati come ingredienti di base per alimentare l'algoritmo in modo da farlo lavorare più di una volta per produrre più di un oggetto. Il modo in cui l'algoritmo lavora (il flusso di lavoro) è semplice. Prevede che ci siano dei dati in ingresso, il processo di questi dati, e un risultato in output. Questo processo avviene in tutto l'algoritmo o, se guardiamo attentamente, in ogni sua singola parte. Quindi invece di usare il metodo di disegno convenzionale, abbiamo bisogno di procurarci le informazioni, le quali verranno processate attraverso un algoritmo e verrà creata una geometria come risultato finale. Come già detto, per esempio, anziché copiare un elemento per '100 volte' nella 'direzione della x positiva' una distanza di '3' possiamo dire all'algoritmo di copiare l'elemento '100 volte' in una 'direzione positiva di X' con un interspazio di 3. Per fare ciò definiamo '100' come numero di copie, 'x positiva' come direzione e '3' come distanza e l'algoritmo farà il lavoro per voi automaticamente. Tutto ciò che facciamo in geometria ha un minimo di matematica alle spalle. Possiamo usare queste semplici funzioni matematiche nei nostri algoritmi con i numeri come oggetti, per generare infinite combinazioni geometriche. Si parte con numeri e insiemi di dati numerici. Diamo un'occhiata, è molto più facile di quanto sembri! 3_1_ Insiemi di dati numerici Tutta la matematica e gli algoritmi iniziano con i numeri. I numeri sono il codice nascosto dell'universo! Per iniziare, prima di tutto abbiamo bisogno di dare un'occhiata ai componenti numerici, per vedere come è possibile generare diversi insiemi di dati numerici in Grasshopper, e quindi il modo in cui li possiamo usare per disegnare qualcosa. Singolo valore numerico Il generatore di numeri più usato è il componente <Number slider> (Params>Special>Number slider) che genera un numero modificabile manualmente. Può essere un intero, reale, pari o dispari con dei limiti inferiori o superiori. Queste impostazioni possono essere regolate dalla voce 'Edit' del menu contestuale. Per impostare un singolo valore numerico potete andare su Params>Primitive>Integer / Number per impostare un valore intero o reale attraverso il menu contestuale di <Int>/<Num> Serie di numeri 22 Possiamo produrre una lista di numeri attraverso il componente <series> (Sets>Sequence>series) Questo componente produce una lista di numeri che è possibile modificare attraverso il primo numero (S), il passo (N), e il numero di valori della serie (C) 0, 1, 2, 3, … , 100 0, 2, 4, 6, … , 100 10, 20, 30, 40, … , 1000000 Range di numeri Possiamo dividere un range numerico tra un valore minimo e massimo con il numero di step e produrre un range numerico. Dobbiamo definire un intervallo per definire il limite inferiore e superiore oltre che il numero di step in cui è diviso (Sets>Sequence>Series) Ogni intervallo numerico (per esempio da 1 a 10) può essere diviso in un numero infinito di parti 1, 2, 3, … , 10 1, 2.5, 5, … , 10 1, 5, 10 23 Domain (Intervals) Domain ('Interval' nelle versioni precedenti) crea un range di numeri reali tra un valore inferiore e superiore. Esistono domini monodimensionali e bidimensionali di cui si tratterà in seguito. E' possibile definire un dominio prefissato usando il componente Params>Primitive> Domain / Domain2 o possiamo andare in Math>Domain>Domain / Domain 2 per generare un gruppo di componenti per lavorare in maniera più flessibili. I domini da soli non producono numeri. Solo solo degli estremi, con un limite superiore e inferiore. Come sapete, ogni due numeri reali ne esistono infiniti. Possiamo usare diverse funzioni per dividerli e usare i fattori di divisioni come valori numerici. Per vedere le differenze e gli usi, proviamo altri esempi. 3_2_ Punti e griglie di punti I punti sono tra gli elementi di base per le geometrie e gli algoritmi generativi. I punti segnano posizioni precise nello spazio, possono essere usati come punti di partenza per le curve, centri di circonferenze, origini di piani o svolgere altri ruoli. In Grasshopper possiamo generare punti in diversi modi: - Possiamo semplicemente scegliere un punto o una serie di punti dalla scena e importarli dentro lo spazio di lavoro attraverso il componente <point> (Params>Geometry>point) ed usarli per qualunque scopo (Questi punti possono essere modificati spostandoli manualmente sulla scena di rhino, e incidere sull'intero progetto – Controllate gli esempi nel capitolo 2). - Possiamo inserire i punti attraverso il componente <point xyz> (vector>point>point xyz) e alimentare le coordinate dei punti attraverso dei numeri, oppure alimentarli da diversi insiemi di dati, in base alle nostre necessità. -Possiamo creare una griglia di punti attraverso i componenti <grid hexagonal> e <grid rectangular> -Possiamo estrarre i punti da altri geometrie in diversi modi, quali punti finali, punti centrali etc (OSNAP) -Talvolta possiamo usare i piani (origini) e i vettori (estremità) come punti di partenze per altre 24 geometrie e viceversa. Avete visto i primi esempi per la creazione di punti nel capitolo 2, ma possiamo dare un'occhiata a delle modalità che producano sistemi di punti attraverso i componenti <series>, <range> e <number slider> e altri strumenti che generano dati numerici. Fig. 3.1 Alimentazione di un componente <point xyz> o <pt> attraverso tre <number slider> per generare un punto, inserendo manualmente le coordinate per x,y e z Fig. 3.2 Generazione di una griglia di punti attraverso i componenti <series> e <pt>. Mentre il <number slider> controlla la distanza attraverso i punti (dimensione dello step) e il secondo controlla il numero di punti nella griglia attraverso il numero di valori del componente <series> (La combinazione dei dati di <pt> è impostata su cross reference per creare una griglia, ma potete provare tutte le combinazioni). Fig. 3.3 Divisione di un range numerico da 0 a 1 attraverso un numero (5) controllabile manualmente e alimentazione di un componente <pt> con la combinazione 'longest list'. In questo caso abbiamo diviso il range per 5, creando 6 punti tra il punto di origine (0,0) e (1,1) sulla finestra di Rhinoceros(è possibile modificare il limite inferiore o superiore del range per modificare le coordinate dei punti. Per fare ciò è necessario cliccare con il tasto destro nel connettore D del componente (indicante il dominio) e modificarlo). In seguito vedremo altri modi per lavorare con gli intervalli e e modificarli. Poiché il nostro primo esperimento sembra facile, possiamo andare avanti, ma dovete provvedere 25 a sperimentare il funzionamento di questi componenti per conto vostro, creando differenti griglie di punti con differenti posizioni e distanze 3_3_ Altri insiemi numerici Set di numeri casuali Vogliamo ora creare una distribuzione casuale di numeri per diversi scopi. Ciò di cui abbiamo bisogno, è un set di numeri casuali al posto dei componenti <series> e <pt>. Selezioni quindi un componente <random> (casuale) da Set>Sequence>Random. Un componente <random> genera una lista di numeri casuali di cui possiamo controllare il dominio. Il componente <random> produce dunque un insieme di numeri casuali, ma noi non vogliamo avere gli stessi valori per x,y e z. Per evitare gli stessi valori, ogni direzione deve avere dei numeri casuali indipendenti. Abbiamo quindi bisogno o di mischiare la lista con i numeri, oppure di tre liste di numeri casuali, create da tre componenti <random> con differenti seeds (il seed, seme, è la parte che 'innesca' la generazione di numeri casuali). Attraverso l'alimentazione del componente <random> per la sua porta S con numeri diversi, generiamo diversi numeri casuali: se non facessimo in questo modo, tutti i componenti random, genererebbero gli stessi valori. Fig. 3.4 Generazione un set di punti casuali. Il componente <random> produce 10 numeri casuali che sono controllati da un <number slider>. La lista è quindi mischiata dal componente <jitter> (Sets>Sequence>Jitter) per le coordinate delle Y, e ancora un'altra volta per le coordinate Z. Volendo è possibile vedere altri ordinamenti di pattern all'interno della griglia (connettendo un <random> alla x, y e z del <pt> senza usare <jitter>). La combinazione di dati è impostata su longest list. In figura 3.4 tutti i punti sono distribuiti in uno spazio compreso tra 0 e 1 in ogni direzione del sistema di riferimento. Per modificare l'area di distribuzione, possiamo modificare il dominio numerico, nel quale il componente <random> produce numeri. Questo è possibile impostando manualmente il 'dominio del range numerico casuale' direttamente su Rhinoceros cliccando con il tasto destro sulla porta R (random numbers domain / dominio dei numeri casuali) del componente o definendo il dominio dell'intervallo modificando i valori attraverso gli slider (fig. 3.5) 26 Fig. 3.5 Impostazione di un dominio attraverso il componente <domain> per modificare l'area di distribuzione dei punti (date un'occhiata alla densità delle griglia in scena rispetto a quella della fig. 3.4) Serie di Fibonacci Che ne dite di creare una griglia con una spaziatura non uniforme? Diamo un'occhiata ai componenti che abbiamo a disposizione. E' necessario dotarsi di una serie di numeri che crescano rapidamente e ancora, sotto la scheda Sets e il pannello Sequence, possiamo trovare il componente <fibonacci> Questo rappresenta una serie di i numeri in cui i primi due numeri definiti (0 e 1) e il numero successivo, sono la somma dei due precedenti. N(0)=0, N(1)=1, N(2)=1, N(3)=2, N(4)=3, N(5)=5, … , N(i)=N(i-2)+N(i-1) Di seguito alcuni numeri della serie: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, … Come potete vedere i numeri crescono velocemente In questo caso ho usato una serie <fibonacci> (Sets>Sequence>Fibonacci) per produrre numeri incrementali che alimentino il componente <pt> Fig. 3.6 Usando una serie <fibonacci> produciamo un incremento delle distanza (con una spaziatura variabile) per generare dei punti. Il numero dei punti può essere controllato con un <number slider> 27 3_4_Funzioni I componenti predefiniti contenuti su Grasshopper, potrebbero non essere sempre il modo migliore per disegnare. Potreste avere bisogno di generare dei dati particolari o almeno manipolare quelli dei componenti esistenti. Per fare ciò, è necessario utilizzare funzioni matematiche e modificare la potenza, le distanze,....di numeri. Il componente funzione è dunque un oggetto capace di eseguire funzioni matematiche su Grasshopper. Esistono funzioni con diverse variabili (Math>Script). Talvolta potrebbe essere necessario alimentare le funzioni con dati pertinenti (non sempre numeri, ma anche valori booleani, stringhe etc) che verranno eseguite in base agli input. Per definire una funzione è possibile cliccare con il tasto destro sulla porta F del componente e digitarla direttamente o usare l'editor di espressioni matematiche. Questo editor, ha tante funzioni predefinite e una libreria di funzioni matematiche come aiuto. E' importante porre attenzione al nome delle variabili da usare nelle espressioni e i dati associati che possono essere combinati nel componente delle funzioni. Funzioni matematiche Come già scritto, usare un componente predefinito non è sempre basta, ma per ottenere i risultati auspicati possiamo usare le funzione matematiche per modificate i set di dati e alimentarli per generare geometrie. Fig. 3.7 Cerchio parametrico creato tramite funzione matematica. Possiamo trovare sia la funzione <sin> (seno) e <cos> (coseno) in Math>Trig. (F(x)=x*2Pi) Fig. 3.8 Altri esperimenti. Serie di punti in cui si è definita una serie <fibonacci> e semplici funzioni matematiche (x: F(x)=x/100, y: F(x)=x/10). La funzione selezionata in verde F(x) è una funzione che aggiunge 2 al valore del <number slider> (F(x)=x+2) per creare valori di una serie equivalenti ai numeri di Fibonacci (la serie di fibonacci ha altri due primi valori). L'obiettivo è di mostrare com'è semplice manipolare questi set di dati e generare di conseguenza diverse geometrie. 28 Fig. 3.9 Un <range> di numeri da 0 a 2 moltiplicato per 2Pi con <Function> che crea un range numerico da 0 a 4Pi. Questo range è diviso in 60 parti. Il risultato alimenta il componente <pt> attraverso la seguente funzione matematica: X=t * Sin(t), Y=t * Cos(t) La conoscenza trigonometriche per i componenti <sin> e <cos> è data per scontata . Per applicare t*sin/cos ho usato il componente <multiplication> da Math>Operators. Qui sarà possibile trovare gli strumenti adatti per ulteriori operazioni matematiche. Fig. 3.10. Eccone una complessa! Algoritmo creata da due spirali invertite create da due insiemi di punti. Il dominio del componente <range> va da 0 a 4, ed è diviso in 400 punti e quindi moltiplicato attraverso la funzione che alimenta i due punti: Primo <pt>: X: F(x) = x * Sin(x*2 Pi), Y: F(x) = x * Cos(x * 2 Pi) Il secondo <pt> ha la stessa funzione ma invertita 29 Fig. 3.11 Moebius da un insieme di punti. <u> e <v> sono componenti <range> successivamente rinominati. Il dominio numerico di ognuno può essere letto nella scena. La funzione matematica che genera un Moebius è la seguente X= Sin(u)*(-2+v*sin(u/2)) Y= Cos(u)*(-2+v*sin(u/2)) Z= v*Cos(u/2) Giocherellare con le funzioni matematiche può portare via un'infinità di tempo! Potrete trovare tante risorse matematiche da combinare i vostri insiemi numerici. La cosa importante è che avete la possibilità di manipolare i dati originali e generare diversi valori numerici, e con questi alimentari altri componenti. Come avete visto da semplici set di dati numerici, è possibile partire per generare geometrie: questo mostra come funzionano gli algoritmi. Da ora in avanti, abbiamo bisogno di costruire la nostra conoscenza basata su diversi concetti geometrici con il metodo degli algoritmi, per affrontare i problemi e le situazioni progettuali, come questa splendida superficie Enneper (dal plugin Math function di rhino) 30 3_5_ Dati Booleani I dati non si limitano ai soli numeri. Ci sono altri tipi di dati che sono utili per differenti scopi nella programmazione algoritmica. Visto che stiamo trattando algoritmi, dovremo sapere che il loro percorso non è sempre lineare. Talvolta abbiamo bisogno di decidere quando fare qualcosa e quando fare altro. I programmatori chiamano questa costruzione 'costrutto condizionale.' Il risultato del costrutto decisionale è un semplice si o no. Per gli algoritmi usiamo i dati booleani per rappresentare questo tipo di risposta. I dati booleani rappresentano solo il TRUE/ VERO e il FALSE/FALSO. Se il costrutto rispecchia i criteri, il responso sarà TRUE, altrimenti FALSE. Come vedremo in seguito, questo tipo di dato è veramente utile in diverse situazioni, soprattutto quando è necessario decidere relativamente a qualcosa, selezionare degli oggetti secondo un criterio, ordinare oggetti etc. Fig. 3.12 Sono stati generati dieci valori <random> e, attraverso il componente <larger> (più grande) (Math>Operators>Larger), voglio vedere se questi numeri sono inferiori ad un determinato <upper_limit> (limite superiore) (valore stabilito tramite un <number slider>) oppure no. Come vedete, se i numeri rispecchiano i criteri (cioè che sono più piccoli del limite superiore), il componente restituirà 'TRUE' oppure 'FALSE' se non li rispecchia. Ho usato il componente <panel> da Params>Special per mostrare il contenuto di <random> e il risultato del componente <larger>. Fig. 3.13 Per il prossimo passo, ho generato 30 valori con il componente <series>. Ho usato il componente <modulus> (Math>Operators>Modulus) per cercare il resto della divisione dei numeri per tre e ho passato il risultato al componente <equals> (uguale) per vedere se il risultato è uguale a zero oppure no. Come puoi vedere il risultato è un altro <panel> con i valori TRUE/FALSE Come potete vedere negli esempi, ci sono diversi possibilità di controllare i criteri attraverso i valori 31 numerici ed avere dei valori booleani come risultati. Ma talvolta è necessario sapere se le situazioni vanno incontro ad altri criteri, e vogliamo decidere in base ai risultati. Per esempio, in base all'esperimento precedente, vogliamo vedere quando un valore è inferiore ad un determinato limite superiore e allo stesso tempo se è divisibile per tre. Per conoscere il risultato, abbiamo bisogno di operare sul risultato di entrambe le funzioni, il che significa che dobbiamo operare con un valore booleano. Se controllate sotto la scheda Math nel pannello Boolean, scoprirete che ci sono diversi componenti che lavorano con i dati di tipo booleano. Fig. 3.14 Combinazione di entrambi i concetti. E' stato usato il componente <Gate And> (Math>Boolean> Gate And) e ho collegato entrambe le funzioni per creare una congiunzione tra loro. Come vedete, questi valori numerici, che sono inferiori di un limite superiori e divisibile per tre, vanno incontro ai criteri e passano il valore TRUE alla fine. Nel pannello Boolean, possiamo trovare diversi operatori booleani, che potete usare in maniera combinata per costruire i vostri criteri decisionali, e costruire i vostri progetti basati su queste responsi. Discuteremo ancora in seguito su come usare i valori booleani. 3_6_ Cull list Ci sono molte ragioni per cui possiamo possiamo avere la necessità di selezionare alcuni oggetti da un dato insieme e non applicare una stessa funzione a tutti. Per fare questo, abbiamo bisogno sia di selezionare alcuni elementi specifici da una lista, sia di ometterne altri. Tra le innumerevoli strade a disposizione possiamo iniziare con quella che ci porta ad omettere / filtrare le liste di dati. Al momento esistono tre componenti di tipo <cull> per filtrare una lista di dati su Grasshopper. Mentre <cull Nth> tralascia un elemento ogni N di una lista data, <cull pattern> prende un pattern di tipo booleano (TRUE/FALSE) e filtra una lista di dati basata su questo pattern. Questo significa che ogni elemento associato ad un valore True nella lista booleane passa, mentre quelli associati a False, vengono omesso dalla lista stessa. <Cull index> invece, filtra una lista di dati attraverso degli indici numerici. Se i numeri dei valori nella lista di dati e nella lista booleana sono gli stessi, ogni elemento della lista di dati viene valutato dal corrispondente elemento nella lista booleana. Ma è possibile definire 32 un semplice pattern di valori booleani (p.e. FALSE/FALSE/TRUE/TRUE già predefiniti nei componenti) e il componente <cull> riepeterà lo stesso pattern per tutte gli elementi della lista di dati. Per capire meglio, vogliamo qui introdurre alcuni modi per poter selezione le nostre geometrie desiderate (in questo caso punti) fuori da un insieme di dati predefinito. Esempio della distanza Pensiamo di selezionare alcuni elementi da un insieme costituito di punti, in base alla distanza da un altro punto (riferimento). Sia i set di punti che il punto di riferimento sono definiti da un componente <point>. Prima di tutto necessitiamo di un componente <distance> (Vector>Point>Distance) che misuri le distanze tra i punti e il riferimento, ottenendo come risultato una lista di numeri (distanze). Compariamo queste distanze attraverso un numero definito dall'utente (<number slider>) con un componente <F2> (Math>Script>f2 / funzione a due variabili). Questo confronto genererà dei valori booleani (True/False) per mostrare sia che il valore sia più piccolo (true) o più grande (false) del limite superiore F=x>y (cioè la stesso andamento del componente <Larger>). Userò per questo scopo, i valori booleani per alimentare il componente <cull pattern>. Come già riferito, <cull pattern> prende una lista di dati generici e una lista di dati booleani e elimina quei membri della lista generica di dati associata con 'False' . In questo caso il risultato del componente <cull pattern> è un gruppo di punti associati al valore TRUE. Ciò significa che sono più vicini al riferimento rispetto al numero specificato nel <number_slider> perché la funzione x>y restituisce sempre un valore TRUE per tutti i numeri più piccoli di Y, il che significa distanze minori (y=distance). Per vedere meglio li ho solo connessi al punto di riferimento attraverso un semplice componente <line> Fig. 3.15 Selezione di punti presi da un insieme attraverso la distanza da un riferimento attraverso il componente <cull pattern>. Esempio topografico Avendo provato la prima distanza logica, voglio selezione alcuni punti che sono associate alla curva di livello su un modello topografico in base loro altezza. 33 Fig. 3.16 Topografia con punti associati alle curve di livello Ciò che ho qui, è un insieme di punti definiti da un componente <point> (chiamato topografia). Ho bisogno dell'altezza dei punti e con la stesso logica dell'esempio sulla distanza, posso selezione gli oggetti desiderati. Ho dunque usato un componente <Decompose> (Vector>Point>Decompose) per ottenere il valore Z delle coordinate dei punti (altezza). Il componente <decompose> mi restituisce le coordinate X,Y, e Z di ogni punto di Input. Ho comparato questi valori con un dato numero (dal <number slider>) con un componente <larger> per creare una lista valori booleani associativi. Il componente <cull pattern> passa i punti associati con il valore TRUE, cioè i punti selezionati saranno più alti di quelli definiti dall'utente per l'altezza. Fig. 3.17 I punti selezionati hanno un'altezza superiore a 4.7550 unità (impostato come valore dell'utente). Questi punti sono ora pronti per piantare i vostri Pini! 3_7_ Liste di dati E' ora quasi chiaro che uno degli algoritmi fondamentali è la lista di dati. La lista di dati potrebbe contenere ogni sorta di oggetti, quali numeri, punti, geometrie e così via. Scorrendo la scheda Sets, sotto il pannello List, ci sono diversi componenti che manipolano liste di dati. Possiamo estrarre un elemento attraverso il loro indice numerico, possiamo estrarre parte di una lista attraverso un indice inferiore e superiore. Queste liste gestiscono gli elementi, aiutandoci ad ottenere una insieme di dati per i nostri scopi progettuali. 34 Fig. 3.18 Lista di punti. Vogliamo selezionare i punti con i valori di x più bassi. Come già detto prima, il componente <point decompose> ci restituisce la coordinate di punti stessi. Ciò di cui abbiamo bisogno è di trovare il valore più basso di X tra tutti questi punti. Per permettere questo, ho bisogno prima di ordinare tutte i valori di X , e poi trovare il minore. Questo è quanto <sort list> farà per noi. Fondamentalmente il componente <sort>, ordina una o più liste di dati, in base ad una lista di dati numerici , come se fossero chiavi ordinabili. Quindi quando queste chiavi sono ordinate, lo saranno anche i dati associati. Qui sono stati dunque ordinati tutti i valori di X come dati chiave. Ciò di cui abbiamo ora bisogno, è di selezionare il primo elemento della lista. Per fare ciò è necessario un componente <item> (elemento ) il cui compito è di estrarre un elemento attraverso il suo indice numerico. Visto che il primo elemento (ad indice zero) ha il valore minore di X, viene estratto l'indice in modo da ottenere come risultato un punto il cui valore di X sia quello minimo dell'insieme,. Vediamo altri esempi Triangoli Sviluppiamo ora i nostri esperimenti con un gestore di dati. Immaginiamo di avere una rete di punti e di voler disegnare delle linee per creare dei triangoli seguendo il pattern mostrato in figura 3.19. Questo concetto è utile per la generazione delle mesh, nella pannelizzazione e in altre situazioni, ma per questa volta è importante essere capaci di produrre i concetti di base. Fig. 3.19 Generazione di triangoli attraverso una rete di punti. 35 Il primo passo è quello di creare una griglia di punti attraverso i componenti <series> e <pt>. Il passo successivo prevede invece di trovare i punti giusti per tracciare delle linee. Ogni volta abbiamo bisogno di una linea che parta da un punto e termini nel punto successivo della stessa riga e colonna successiva, e poi un'altra linea che vada da quest'ultimo punto alla colonna precedente e alla riga successiva ed una linea finale che torni indietro al punto di partenza. Per farlo sarebbe meglio fare tre liste di punti, una per ogni 'primo punto', una per ogni 'secondo punto' e un'altra per ogni 'terzo punto' e quindi disegnare delle linee. E' possibile usare il punto originale come la lista per tutti i punti di partenza. Il primo 'secondo punto' è il secondo punto nel gruppo di punti e quindi la lista va avanti, uno alla volta. Quindi per selezione il 'secondo punto' ho solo spostato la lista originale tramite il componente <shift list> (Sets>list>Shift list) con una distanza di spostamento pari a 1, il che significa che il secondo elemento della lista (indice 1) diventa il primo elemento (indice 0) e il resto della lista procede allo stesso modo. Questa nuova lista è la lista del 'secondo punto' I 'terzo punto' dei triangoli sono nella stessa colonna dei 'primo punto' ma nella riga successiva. In termini di indici numerici, se la griglia contiene N colonne, il primo punto della seconda riga ha l'indice pari all'indice del primo punto (0)+N In una griglia con 6 colonne, l'indice del primo punto della seconda riga è 6. Ho qui spostato ancora la lista originale di punti con una distanza di spostamento pari al numero delle colonne, in modo da ottenere il primo punto della riga successiva (la distanza di offset dipende dal <number slider> che indica il numero di colonne) per trovare tutti i terzi punti. Fig. 3.20 L'elemento selezionato è il punto spostato attraverso una distanza di spostamento pari al numero di colonne che producono tutti i 'terzo punto' dei triangoli. Per completare l'operazione abbiamo bisogno di manipolare questa lista un po' di più, quindi concentratevi ancora: 1. Prima di tutto, nella lista 'primi punti' i punti dell'ultima colonna non potranno mai essere i primi punti della lista 'secondo punto'. 2. Anche i punti della prima colonna non potranno mai essere 'secondo punto', abbiamo quindi bisogno di eliminarli dalla lista 'secondo punto'. 3. Stessa cosa per i 'terzo punti', dove i punti nell'ultima colonna non potranno mai essere i terzi punti. 36 Se combiniamo tutte queste tre parti, li immaginiamo e li disegniamo, capiremo che in tutte queste tre liste, i punti dell'ultima colonna non potranno essere usati. Fondamentalmente, abbiamo quindi bisogno di omettere l'ultima colonna da ciascuna lista di dati. Ed è per questo che abbiamo collegato tutte le liste di punti ad un componente <Cull Nth>. Questo componente, elimina un elemento ogni N numeri di una lista di dati ed N viene chiamata frequenza di raccolta (cull frequency) (Fig 3.20). In questo caso tutte le liste di dati sono filtrate attraverso il numero di colonne. Questo perchè, per esempio, se abbiamo 6 colonne, elimina ogni un elemento ogni sei, cioè l'elemento dell'ultima colonna. Il risultato sarà dunque una nuova lista con le ultime colonne eliminate. Abbiamo quindi connesso il <number slider> che definisce il numero di colonne ad ogni componente <cull nth> per stabilire la frequenza di raccolta. Fig. 3.21 Usiamo <cull nth> per eliminare le ultime colonne dalle prime, seconde e terze liste di punti. L'ultimo passo è quello di alimentare i componenti <line> e connettere i primi punti ai secondi, quindi i secondi con i terzi e per finire, i terzi con i primi. Fig. 3.22 Creazione delle linee tramite le connessione dei punti della lista filtrata al componente <line>. Non dimenticate di impostare l'opzione cross reference per il componente <pt> , e longest list per il componente <line> . 37 Fig. 3.23 Ora modificando il <number slider> è possibile avere diverse griglie di punti che producono questi triangoli. Sebbene ci siano ancora diversi problemi con il nostro progetto, sappiamo che non vorremo far partire alcun triangolo dai punti dell'ultima riga (e dovremo eliminarli dalla lista dei 'primi punti'), ma il concetto è chiaro....andiamo avanti. Torneremo indietro a questo concetto quando parleremo delle geometrie mesh e proveremo a limare i concetti. L'idea principale è quella di vedere come i dati possono essere generati e maneggiati. Porteremo avanti i concetti attraverso altri esperimenti. 3_8_ Pattern per geometrie planari I pattern geometrici sono tra le tematiche più interessanti da trattare con gli algoritmi generativi in Grasshopper. Abbiamo il potenziale per disegnare dei motivi e quindi farli crescere come pattern che possono essere usati come base per altri prodotti progettuali. Nel caso di progettazione di pattern, possiamo dare un'occhiata al nostro progetto/modello ed estrarre la logica che produce l'intera forma nel momento stesso in cui viene ripetuta. Attraverso il disegno della geometria di base, possiamo copiarla per produrre i pattern delle dimensioni volute(Fig. 3.22) 38 Fig. 3.24 Estrazione del concetto del pattern da geometrie semplici. Continuiamo ad insistere sul lavorare attraverso gli insiemi di dati e sulle semplici funzioni matematiche, invece di usare altri utili componenti proprio per vedere come queste semplici operazioni e gli insiemi di dati numerici abbiano un grande potenziale per generare forme, anche geometrie classiche. Fig. 3.25 Geometrie complesse nella Moschea Sheikh Lotfollah in Iran. Le mattonelle sono formate da pattern semplici, che sono create attraverso calcoli matematico/geometrico. Pattern lineari semplici Ho qui deciso di progettare un pattern con alcuni punti di base e linee. L'obbiettivo è quello di usare concetti semplici come quelli in figura 3.26 39 Fig. 3.26 Concetti di base per generare pattern Prima di tutto vogliamo generare alcuni punti di base come geometrie di partenza e quindi disegnare le linee tra questi punti. Ho iniziato la mia definizione, tramite una <series> che rende possibile il controllo dei valori numerici (numero di punti), la dimensione del passo ( distanza tra punti). Attraverso questa <series> ho generato un insieme di punti con solo valori sulla X (con y e z pari a zero). Fig. 3.27 Sono stati generati il primo set di punti con i componenti <series> e <pt>. Aggiungiamo qui un componente <receiver> che possiamo trovare in Params>Special>Receiver. Questo componente prende i dati da un altro componente e li passa ad un altro rimuovendo i cavi di connessione dal canvas. In progetti complessi, quando si voglia usare una sorgente di dati per tanti componenti, ci aiuta a ripulire l'area di lavoro in modo da evitare distrazioni dovute alle tracce delle connessioni. Come potete vedere nella seconda figura, il componente <receiver>, riceve i dati da <series>. Fig. 3.28 Per creare una forma a zig zag abbiamo bisogno di due righe di punti come geometria di base. E' stato usato un altro <receiver> per avere dati da una <series> e con un altro <pt> è stato generata la seconda riga di punti aventi valori y, provenienti da un <number slider> 40 Fig. 3.29 Nei passi successivi, dobbiamo eliminare alcuni punti da ogni lista per procurarci i punti per il pattern a zig zag. Qui sono stati eliminati i punti attraverso un <cull pattern>, in una riga usando il pattern booleano TRUE/FALSE e nell'altra usando FALSE/TRUE Fig. 3.30 Ora se connette entrambi i componenti <cull> ad un componente <poly line> da Curve>spline>Polyline che disegna curve lineari passanti più vertici anziché solo due, vedrete come risultato delle linee che formano una Z. Questo perchè i punti non sono ordinati e devono essere posizionati in una lista in questa sequenza: primo punto della prima riga, primo punto della seconda riga, secondo punto della prima riga, secondo punto della seconda riga. 41 Fig. 3.31 Il componente che ordina i punti nel modo descritto è il <wave> (Sets>list>Wave). Prende i dati da diverse fonti e li ordina in base ad un pattern che dovrebbe essere definito nella sua porta P (come sempre, leggete l'help del componente per vedere le informazioni più dettagliate). Il risultato sarà una lista di elementi ordinati che una volta connessi ad componente <pline> mostreranno il primo zigzag. Fig. 3.32 Con lo stesso concetto, è stata generata la terza riga di punti, e con un altro componente <weave> e <pline>, è stata disegnata una seconda linea a zig-zag 42 Fig. 3.33 Sebbene ci siano dei modi più veloci per generare queste linee, anche qui ho usato lo stesso concetto per i punti e polilinee della terza riga. E' stata deselezionata l'opzione preview (anteprima) per <pt>, <cull> e <weave> (dal loro menu contestuale) per nascondere tutti i punti e vedere la sola polilinea. Fig. 3.34 Se si copia ancora lo stesso processo e questa volta invertiamo il valore di Y del componente <pt> in negativo, (possiamo usare lo stesso <number slider> con una funzione di tipo f(x)=-x) si otterrà un gruppo di polilinee specchiate. Ora, manipolando le distanze, è possibile avere dei pattern con scale e forme diverse. Fig. 3.35 E' possibile cambiare il modo con cui generate i punti di base o filtrate dati delle liste. Il risultato potrebbero essere pattern diversi, di semplici intersezioni di linee, ma potrebbe essere una geometria generativa per produrre modelli complessi. Fig. 3.36 Questo è il primo risultato del progetto. Il motivo viene ripetuto in maniera semplice e il 43 risultato può essere usato in ogni modo, in base alle varie necessità. Fig. 3.37 Questo è solo uno degli esempi tra le centinaia di possibilità per usare i pattern come base di sviluppo per i progetti. In seguito avrete le potenzialità per differenziare i pattern di base e per modificare i risultati dei progetti. Pattern circolari La modellazione associati ci permette di infinite possibilità per creare motivi e pattern. La fig. 3.38 mostra altri motivi in cui i disegni sono basati sulla geometria circolare anzichè che quella lineare. Poichè vi sono diverse curve aventi tutte la stessa logica, verrà descritta una parte degli algoritmi mentre il resto spetterà a voi. Fig. 3.38 Pattern geometrico circolare. Il punto di partenza di questo pattern è un insieme di dati che produce una serie di punti lungo una circonferenza, come l'esempio fatto in precedenza. Questi dati possono essere scalati dal centro per creare diverse circonferenze concentriche. Questo set di punti verrà filtrato allo stesso modo 44 dell'ultimo esempio. Quindi verrà generato un pattern zig zag ripetitivo tramite questi punti scalati, i quali, una volta connessi l'uno con l'altro, disegneranno una curva a forma di stella. La sovrapposizione di queste stelle potrebbe creare una parte di questo motivo. Fig. 3.39 Creando un range da 0 a 2Pi e usando le funzioni di seno e coseno, creiamo il primo gruppo di punti in una geometria circolare. Ho usato questa funzione con due variabili per moltiplicare il risultato di seno e coseno attraverso un altro <number slider> per cambiare il raggio di una circonferenza. Fig. 3.40 Incremento di seno e coseno, grazie alla moltiplicazione attraverso da un <number slider> e creazione del secondo insieme di punti con un raggio maggiore. Come potete vedere il risultato di questa sezione è un set di due punti. I componente <pt> sono stati rinominati. 45 Fig. 3.41 La prima e la seconda circonferenza di punti Per poter filtrare i punti, possiamo semplicemente usare il <cull pattern> per i punti e usare TRUE/FALSE come nell'ultimo esempio. Ma come è possibile ordinare la lista di punti? Se anche è possibile usare lo stesso metodo, qui ho deciso di optare per un altro, in modo da usare un altro concetto relativo all'ordinamento, che crediamo possa usare utile in seguito: vogliamo ordinare i punti in base al loro indice numerico nell'insieme. Prima di tutto abbiamo bisogno di generare un indice di numeri. Visto che abbiamo prodotto un componente <range> di numeri reali, abbiamo bisogno di un componente <series> per procurarci numeri interi come indici dei punti nella lista. Gli N parametri del <range> definiscono il numero dei passi o delle divisioni, quindi il componente <range> produrrà N+1 numeri. Ed è per questo che necessitiamo di un <series> con N+1 valori per essere gli indici dei punti. Fig. 3.42 Generazione dell'indice numerico per i punti (la lista di numeri interi parte da 0) 46 Fig. 3.43 A questo punto ho bisogno di scegliere i punti e gli indici come nell'esempio precedente. Ho quindi usato il componente <Merge> (Sets>Tree>Merge) per generare una lista di dati entrambe le liste <cull>. L'operazione è stata applicati sia ai punti che agli indici. Sebbene il risultato dell'unione delle <series> produrrà ancora i numeri dell'intero set di dati, l'ordine non sarà lo stesso e sarà più vicino a quello dei punti. Ora attraverso l'ordinamento degli indici come chiavi ordinate, possiamo ordinare allo stesso modo anche i punti. 47 Fig. 3.44 I punti sono ordinati con un componente <sort> mentre la loro chiave di ordinamento è l'indice. Viene disegnata una polilinea tra i punti ordinati. Fig. 3.45 Gli indici prima e dopo l'ordinamento, e i punti ordinati e associati che generano una polilinea a forma di stella La stessa logica potrebbe essere usate per creare geometrie più complesse con una semplice generazione di set di altri punti, filtrati e connessi per produrre i pattern desiderati. Il trucco è quello di scegliere il miglior gruppo di punti e il modo di connetterli ad altri set. 48 Fig. 3.46 E' possibile pensare ad altre possibilità di pattern e di geometrie lineari e loro applicazioni come per esempio, le proiezioni su altre geometrie. Sebbene abbia insistito per genere tutti i precedenti modelli attraverso set di dati e semplici funzioni matematiche, vogliamo vedere altri semplici componenti che rendono possibile ridurre l'intero processo o modificare il modo in cui recuperiamo i dati. Li discuteremo tutti insieme Fig. 3.47 Modello Finale 49 CAPITOLO 4_ Trasformazioni 50 Capitolo 4_ Trasformazioni Le trasformazioni sono operazioni essenziali, sia nella modellazione che nella geometria generativa. Permettono infatti di ottenere variazioni da semplici oggetti iniziali, aiutandoci a scalare, orientare, muovere, copiare o specchiare le nostre geometrie. Esistono diversi tipi di trasformazioni, ma per classificarle le possiamo dividere in gruppi: la prima divisione che possiamo indicare è quella tra trasformazioni lineari e trasformazioni spaziali. La trasformazione lineare è attuata in uno spazio 2D, mentre quella spaziale avviene in uno 3D. Un altro modo per classificare le trasformazioni, potrebbe essere quello di dividerle in base allo stato iniziale dell'oggetto: trasformazioni quali traslazioni, rotazioni, riflessioni, mantengono la forma originale, mentre la scalatura e l'inclinazione la modificano. Esistono anche della trasformazioni non lineari. In aggiunta alla traslazione, rotazione e riflessione, abbiamo diversi tipi di deformazioni e scale non uniforme nello spazio 3D, oltre che trasformazioni spiraliformi o a forma di elica e proiezioni che creano variazioni nello spazio tridimensionale. Per poter trasformare, dobbiamo muovere o orientare gli oggetti ( o loro parti, quali vertici o angoli ) nello spazio, e per fare ciò abbiamo bisogno di usare vettori e piani come basi per queste operazioni matematico/geometriche. Non discuteremo le basi della geometria o della logica matematica, ma daremo un'occhiata ai vettori e ai piani, perchè ci serviranno per il nostro lavoro. Fig. 4.1 Le trasformazioni palesano grandi potenziali nelle generazioni di forme complesse partendo da quelle semplici. La natura presenta nelle sue opere grandi esempi di trasformazioni. 4_1_ Vettori e Piani Il vettore è un oggetto matematico che presenta un modulo (o lunghezza), una direzione ed un verso. Parte da un punto, procede in direzione di un altro in una specifica direzione. I vettori hanno una ampio raggio di utilizzo e sono usati, oltre che per le trasformazioni, in diversi campi della scienza e della geometria. 51 Fig. 4.2 Elementi base di un vettore; spostamento di un punto tramite un vettore Se abbiamo un punto ed un vettore, questo vettore può trasportare il punto alla distanza data dal modulo e verso una direzione stabilita, in modo da creare una nuova posizione finale per il punto stesso. Useremo questo semplice concetto per generare, muovere, scalare e orientare le geometrie con il nostro metodo associativo. I piani sono un altro gruppo di geometrie utili e possono essere descritti come superfici piatte e infinite, aventi un punto di origine. I piani di costruzioni di Rhino, rappresentano questo tipo di oggetto. Possiamo usare questi piani per inserirci le nostre geometrie, applicare determinate trasformazioni basate sul loro orientamento e origine. Per esempio, nello spazio 3D, non possiamo orientare un oggetto su un solo vettore, ma abbiamo bisogno di due vettori per creare un piano capace di contenere la geometria. I vettori hanno una direzione e un modulo mentre i piani hanno un orientamento ed un'origine rappresentati da X, Y e Z quali vettori unitari e i piani XY, XZ e YZ. Nei prossimi esempi tratteremo di altri diversi componenti che li producono e li modificano. Iniziamo dunque i nostri esperimenti progettuali partendo con uno degli usi più semplici per i nostri vettori, per poi andare avanti passo dopo passo. 4_2_Curve e geometrie lineari Abbiamo già fatto esperimenti con i punti che sono geometrie a dimensione 0, possiamo ora iniziare a pensare alle curve come a degli oggetti monodimensionali. Come i punti, le curve possono essere la base per costruire diversi tipi di oggetti. Possiamo estrudere una curva lungo un'altra per creare una superficie, possiamo collocare diverse curve insieme per creare superfici e quindi solidi, possiamo distribuire ogni oggetto lungo una curva con uno specifico intervallo o possiamo pensare tanti altri modi per sfruttare questa geometria come base per generare altri oggetti. 52 Spostamenti Nel capitolo 3, abbiamo generato diverse griglie di punti attraverso i componenti <seris> e <pt>, ma ora è giunto il momento di introdurre un altro componente, chiamato <grid rectangular> (Vector>Grids>Grid rectangular) che produce una griglia di punti. Possiamo controllare sia le distanze tra i punti (uguali in entrambe le direzioni) che la quantità sia in direzione X che Y. Fig. 4.3 Un semplice componente <grid rectangular> con i suoi valori predefiniti. E' possibile cambiare la dimensione della griglia attraverso un <number slider> connesso all'input (S) indicante la distanza. Possiamo inoltre anche modificare l'orientamento dei punti. Per fare ciò abbiamo bisogno di un piano su cui inserire la griglia. Abbiamo introdotto il componente <XY plane> (Vector>Plane>XY plane) che rappresenta un piano infinito nell'orientamento prodotto dagli assi X e Y e lo abbiamo spostato lungo l'asse Z, attraverso il componente <Z unit> (Vector>Vector>Z Unit) che rappresenta un vettore parallelo all'asse Z con la lunghezza pari a uno. Possiamo modificare l'altezza di questo spostamento attraverso la dimensione del vettore collegandolo ad un <number slider> connesso con l'input del componente <z unit>. Modificando la posizione del <xy plane> lungo l'asse Z, sarà possibile cambiare la posizione della griglia Fig. 4.4 Le griglie (selezionate in verde) sono modificate da un <number slider> che scala la distanza tra i punti, e da un altro slider connesso ad un <z unit> e un <xy plane> per modificare le coordinate dei punti della griglia sull'asse Z. 53 Quindi, se date un'occhiata al risultato di una <grid rectangular> è possibile vedere che abbiamo accesso a tutti i punti delle celle della griglia e i centri delle celle. Per questo esperimento, cerchiamo un insieme di linee che partono dal centro delle celle della griglia, ed escono verso lo spazio. Possiamo semplicemente connettere i punti dai due componenti <grid> attraverso la porta M al componente <line> per generare un gruppo di linee. Quindi cambiando le dimensioni della seconda griglia verranno disegnate delle linee con direzioni diverse. Il problema è dato dalla lunghezza delle linee, che in questo caso sarà diversa una dall'altra, mentre noi vogliamo disegnare linee della stessa lunghezza. Per fare ciò abbiamo bisogno di un'altra strategia ed è per questo che andremo ad usare il componente <line SDL>. Un componente <line SDL> disegna una linea partendo da un punto (S), con una direzione (D) ed una lunghezza (L). Quindi la lunghezza delle linee è controllabile. Esattamente ciò di cui abbiamo bisogno; abbiamo sia il punto di partenza (centro della cella) che la lunghezza della linea (qualunque sia). E per quanto riguardo la direzione? Vogliamo usare il punto centrale delle celle della seconda griglia quale secondo punto delle linee, quindi la direzione delle mie linee sarà la direzione delle linee connesse al punto centrale della griglia. Per definire queste direzioni abbiamo bisogno di vettori. Ed è per questo che creiamo un set di vettori con queste due punti per creare le direzioni per il mio componente <line SDL>. Fig. 4.5 Creazione di vettori dal punto centrale della prima griglia verso il punto centrale della celle della seconda griglia attraverso il componente <vector 2p> (Vector>Vector>vector 2pt). Questo componente crea dei vettori attraverso il suo punto di partenza e di arrivo. Fig. 4.6 Il componente <line SDL> genera diverse linee dal punto centrale di una griglia che si muove verso lo spazio a causa della maggior distanza della seconda griglia. E' possibile cambiare la lunghezza di linee attraverso il <number slider> ed è possibile cambiare la loro direzione cambiando la dimensione della seconda griglia. 54 Per il passo successivo vogliamo aggiungere un poligono alla fine di ciascuna linea ed estruderlo verso il punto di inizio delle linee per vedere il potenziale generativo. Per generare i poligoni abbiamo aggiunto diversi piani ai punti finali delle linee come piano base per poter creare dei poligoni. Fig. 4.7 Usando il componente <end point> (Curve>Analysis>End Point) e usando questo punto finale quale punto di origine per un set di piani è possibile generare i piani di base. E' stato qui usato il componente <Plane Normal> (Vector>Plane>Plane Normal) che produce una piano per un punto di origine (punti finali delle linee) e un vettore di direzione Z normale al piano (un vettore normale, è un vettore perpendicolare al piano). Abbiamo qui usato gli stessi vettori delle linee come direzioni normali per i piani. Fig. 4.8 Aggiunta di un componente <polygon> e uso dei piani generati come piani di base per i poligoni, questo produrrà un set di poligoni alla fine di ogni linea e perpendicolare alle linee stesse. Come potete vedere questi poligoni hanno la stessa dimensione, ma vogliamo applicare un sistema di diversificarne le misure per avere una forma smussata alla fine. 55 Fig. 4.9 Con un componente <list lenght> otteniamo i numeri delle linee, mentre il componente successivo <function> il quale è una radice quadrate dell'input (F(x)=Sqrt(x)), calcola il numero delle linee per ogni riga. E' stato usato un componente <series> con il punto di partenza con la dimensione del passo pari a 0.1, mentre il numero dei valori proviene dal numero delle righe. E' stata quindi generata una lista di numeri che crescono gradualmente, in numero pari a quello dei poligoni di ciascuna riga. Per poter usare questi valori per tutti i poligoni, sono stati duplicate le liste di dati con il valore delle colonne (in questo caso uguale a quello delle righe) e collegate all'Input del raggio dei poligoni. Come potete vedere nel modello, ad ogni riga, le dimensioni dei poligoni gradualmente si modifica e questo pattern si ripete fino all'ultimo. Fig. 4.10 Nell'ultimo passo, è stato usato un componente <extrude point> (Surface>freeform>Extrude Point) e collegato il punto iniziale della linea quale punto verso il quale voglio venga estruso il mio poligono. 56 Fig. 4.11 Usando il 'Remote control panel' cioè il pannello di controllo in remoto, si può facilmente cambiare il valore dei numeri per diverse opzioni e controllare l'aspetto finale del modello e selezionare il migliore. Non dimenticate di deselezionare l'anteprima per gli oggetti non necessari. 57 Fig. 4.12 Modello finale 4_3 Esperimento combinato: Swiss Re Oggigiorno è molto comune progettare il concetto delle torri con il metodo della modellazione associativa. Questo permette ai progettisti di generare modelli differenziati, in maniera facile e veloce. Il potenziale per differenziare i progetti è molto vasto e i risultati migliori possono essere ottenuti velocemente. Abbiamo deciso di modellare una torre, e la “Swiss Re” di “Foster and Partner” sembra essere abbastanza sofistica per un esperimento di modellazione. Innanzitutto diamo un'occhiata al progetto 58 Fig.4.13 Swiss Re HQ, 30 St Mary Axe, London, UK, 1997-2004, Fotografie provenienti dal sito web di Foster and Partners , http://www.fosterandpartners.com. Innanzitutto l'idea: stiamo per disegnare delle circonferenze per identificare l'ingombro della torre e copiarli in modo tale da formare i piani nei quali la facciata cambi curvatura. Scaleremo i piani per farli combaciare alla forma, e quindi costruiremo il rivestimento usando i piani. Per concludere, aggiungeremo delle sezioni poligonali per gli elementi strutturali della facciata. Per fare questo ipotizzerò sia le dimensioni che le proporzioni e mi occuperò del modello con geometrie semplici in modo da rendere più facile il processo. Partiamo con i piani. Sappiano che i piani della Swiss Re sono delle circonferenze che hanno alcuni tagli a forma di V, ma qui abbiamo usato una semplice circonferenza come profilo. Copiamo questi piano ad una certa altezza, il che renderà possibile poter giocare visualmente con le proporzioni. Come già detto, questi punti sono posizionati nei punti in cui cambia la curvatura della facciata. Fig. 4.14 Componente <circle> con un <number slider> come raggio esterno della torre. Questa circonferenza è copiata per sei volte lungo la direzione Z positiva, grazie al componente <move>, attraverso un vettore <z unit> . Questi numeri sono forniti attraverso l'impostazione manuale 'set 59 multiple numbers' e sono assunti quali distanze delle diverse parti della torre (fatta sulla base della dimensione della circonferenza di partenza). Sebbene siano state generate queste circonferenze di base tutte uguali, sappiamo che i piani non hanno la stessa dimensione, e abbiamo quindi bisogno di riscalarli. Se diamo un'occhiata alla sezione della torre, vedremo che dalla base le circonferenze iniziano a crescere fino ad una certa altezza, rimangono costanti nella parte centrali e quindi iniziano a decrescere fino alla punta della torre. Anche qui ipotizzeremo i fattori di scala per i piani. Sarà possibile modificare questi valori per verificare che il progetto risulti simile a quello originale. Fig. 4.15 Abbiamo bisogno di un componente <scale> (Xform>Affine>Scale) per ridimensionare i piani di riferimento. Il componente <scale> necessita di una geometria da modificare, un punto di riferimento ed un fattore di scala. Abbiamo quindi bisogno di alimentare la parte geometrica attraverso i nostri piani o circonferenze che risulteranno essere l'output del componente <move>. Il centro predefinito per la scalatura è il punto di origine ma se scaliamo tutti i piani attraverso lo stesso centro, questi verranno spostati nello spazio poiché verrà scalata anche la loro altezza. Abbiamo quindi bisogno che il centro di scalatura della torre sia allo stesso livello di ogni piano. Dovrebbe esserci uno per ognuno ed esattamente al centro del pavimento. Per questo motivo abbiamo usato il componente <centre> (Curve>analysis>center) che ci restituisce il centro delle circonferenze. Connettendolo al <scale> potremo vedere che tutte le circonferenze saranno scalate al loro livello senza spostamenti. Ricordiamo che i fattori di scala sono presunti, proprio come quelli delle altezze fatte in precedenza. Questi valori possono essere cambiati per vedere quale combinazione calza meglio alla visuale totale. Sono tutti impostati da un componente <number>. 60 Fig. 4.16 Se ora applichiamo una superficie loft a questi piani (attraverso un componente <loft> (surface>freeform>loft)), apparirà la prima immagine della torre. Piano piano, dovremo deselezionare l'opzione di anteprima dai punti generati in precedenza per ripulire la scena. A questo punto possiamo iniziare gli elementi di facciata. Gli elementi strutturali della facciata sono di forma elicoidale, ed hanno una sezione composta da due triangoli interconnessi, ma per semplificare modelleremo solo la parte visibile, la quale somiglia ad un triangolo in piano. Useremo il loft tra queste sezioni per creare il loro volume. Vogliamo generare queste sezioni triangolari sulla facciata. Per fare ciò, abbiamo prima bisogno di trovare la posizione di questi triangoli sulla facciata. Penso che se creiamo una curva sulla superficie della facciata e le dividiamo, potrebbe risultare in un posto accettabile per posizionare tutti i triangoli prima di ogni trasformazione. Fig. 4.17 Abbiamo usato il componente <end point> per avere i punti iniziale/finale dei miei piani campione. Collegando questi punti come vertici di un componente <interpolate> (curve>spline>interpolate) sarà possibile avere una curva posizionata nella facciata. 61 Fig. 4.18. Qui sono state divise le curve <interpolate> in 40 parti. Il numero delle divisioni aiuta alla smussatura degli elementi quando vorremo regolare la facciata. Fig. 4.19 Ora i punti di divisione diventano punti di base per generare i <polygon> sulla facciata. Sono state impostati tre lati per generare triangoli e la loro dimensione, la parte 'R' (raggio) è controllabile attraverso un <number slider> Fig. 4.20 Gli elementi della facciata strutturale sono spirali che girano attorno alla pelle, fino alla punta superiore della torre. Per permettere questo, dobbiamo ruotare le sezioni triangolari gradualmente. Vogliamo usare il componente <rotate> e per questo abbiamo bisogno degli angoli di rotazione. Come detto, gli angoli di razione dovrebbero essere una lista di numeri che crescono 62 gradualmente. Il componente <series> genera i nostri angoli di rotazione e contiene elementi in numero pari al componente <divide> (punti-triangoli). Come risultato tutte le sezioni triangolari ruotano attorno alla facciata. Fig. 4.21 Ora dobbiamo creare un loft tra tutti i triangoli, e vedremo apparire un singolo elemento di facciata. L'angolo di rotazione e le dimensione degli elementi saranno controllabili in modo da far combaciarli con la facciata nel suo modo migliore. Domains Come già detto il Dominio è un intervallo numerico. Sono numeri reali che vanno da un limite inferiore ad uno superiore. Poiché abbiamo parlato di numeri reali, significa che tra due numeri appartenenti a questo insime, abbiamo infiniti numeri, il che permette diversi tipi di utilizzo per questi domini numerici. Come già sperimentato prima, possiamo dividere il range numerico ed avere le divisioni equamente distribuite attraverso due estremi. Vogliamo dunque distribuire gli elementi della facciata attorno alla circonferenza di base. Per fare ciò abbiamo bisogno di un intervallo per coprire l'intera circonferenza di base. 63 Fig. 4.22 Un componente <domain> (Math>Domain>Domain ) è stato usato per definire un range numerico da 0 a 360. Questo intervallo numerico è diviso attraverso un componente <range> in 10 parti e il risultato è usato come fattore angolare per un componente <rotate>. Quindi come mostrato nell'immagine, gli elementi di facciata sono distribuiti nella circonferenza di base. Fig. 4.23 Se facciamo un <mirror> (specchio)(Xform>Euclidian>Mirror) attraverso un <XY plane> (Vector>Plane>YZ plane) delle geometria, avremo gli elementi della facciata in una forma elicoidale specchiata che alla fine produrrà un reticolo attorno alla torre. Fig. 4.24 Ecco un'altra anteprima della facciata che mostra una rappresentazione non rifinita della “Swiss re” con una tecnica associativa. 64 Fig. 4.25 Per generare la geometria su Rhino, selezioniamo i componenti che creano le geometria desiderata, e quindi optiamo per 'bake selected object', dalla barra sopra il canvas o dal menu contestuale del componente. Fig. 4.26 Modello finale. Sebbene non sia identico all'originale, per essere un modello di partenza e creato in poco tempo, funziona bene. 65 Fig. 4.27 In mezzo agli elementi strutturali principali, ci sono altri piccole strutture che potete modellare da soli. Immagini dell'autore 4_4_ Attrattori 'L'attrattore è un insieme di stati verso il quale tende ad evolvere un sistema fisico dinamico, senza tener conto delle condizioni di partenza del sistema. Un punto attrattore è un attrattore che consiste in un singolo stato. Per esempio, una pallina che rotola in una tazza si fermerà alla fine, sempre nel punto più basso, al centro inferiore; lo stato finale della posizione una volta terminato il moto è un punto di attrazione' (Dictionary.com/Science Dictionary). Fig.4.28. Strange Attractor (Illustrazione presa da http://www.cs.swan.ac.uk/~cstony/research/star/) 66 Nel caso della progettazione e della geometria, gli attrattori sono elementi (solitamente punti ma potrebbero essere anche curve o ogni altra geometria) che producono effetti su altre geometrie nello spazio, cambiando il loro comportamento facendoli spostare, ri-orientare, riscalare etc. Possono articolare lo spazio attorno a loro stessi e introducono il campo del raggio di attrazione. Gli attrattori hanno diversi applicazioni nel design parametrico, poiché hanno il potenziale di modificare tutti gli oggetti costantemente. Definendo un campo, gli attrattori possono inoltre influenzare gli agenti di un sistema con diverse azioni. Le modalità di influenza e la potenza degli attrattori, dipendono da parametri regolabili. Vedremo il concetto di attrattori in diverse occasioni, quindi iniziamo subito con i primi semplici esempi. Punti di attrazione Abbiamo una griglia di punti e vogliamo generare un set di poligoni a partire da questi punti. Abbiamo inoltre un punto chiamato <attractor 1> a cui abbiamo disegnato attorno un <circle>, giusto per renderlo più chiaro. Voglio che il mio <attractor_1> influenzi tutti i miei <polygon> nel suo campo di azione. Significa che, in base alla distanza tra ogni <polygon> e il <attractor_1> e nel dominio di <attractor_1> ogni <polygon> risponde all'attrattore modificando la sua dimensione. Fig. 4.29 Base di <point_grid> con <polygon> e <attractor_1> L'algoritmo è veramente semplice. In base alla <distance> tra <attractor_1> e il <pt-grid> vogliamo influenzare il raggio del poligono, in modo che la realzione tra gli attrattori e i poligoni sia definita in base alla distanza. Necessitiamo di un componente <distance> per misurare la distanza tra <attractor_1> e il centro del poligono o la <pt_grid>. A causa del numero che potrebbe essere troppo grande, abbiamo bisogno di <divide> (Math>Operators>Division) la distanza con un numero dato da un <number slider> per ridurre la potenza di <attractor_1> a mio piacimento. 67 Fig. 4.3 La <Distance> viene divisa con un numero per controllare la potenza del componente <attractor_1>. Sebbene abbiamo creato un gruppo attraverso <attractor_1> e la sua circonferenza, sembra che la nuova versione di Grasshopper non accetti più i cluster, ed è quindi consigliabile usare un semplice <pt> come <attractor_1> Se ora connettiamo il componente <div> al raggio (R) del poligono, potremo vedere che la scala del poligono aumenta quando ci avviciniamo all' <attractor_1>. Sebbene questo possa sembrare un buon risultato, vogliamo controllare il raggio massimo del poligono, altrimenti andando oltre, c'è il rischio che diventino troppo grandi, intersecandosi uno con l'altro (è la stessa cosa che succede se la potenza degli attrattori è troppo grande). Dobbiamo quindi avere un controllo manuale del raggio del poligono. Fig. 4.31 Usando un componente <minimum> (Math>Util>minimum) ed un numero definito dall'utente, creiamo un costrutto decisionale che dice all'algoritmo di scegliere il valore dal componente <div> se è più piccolo del numero che abbiamo definito come raggio massimo attraverso il <number slider>. Come potete vedere dalle immagini, questi poligoni che crescono per diventando più grandi del <max_rad> rimangono costanti, e possiamo dire che non sono sotto l'azione del campo di attrazione. Se nell'area di lavoro di Rhino, cambiamo manualmente la posizione del <attractor_1>, possiamo vedere che tutti i poligono avranno il loro raggio in accordo con la posizione di <attractor_1> 68 Fig. 4.32 Effetti dell'attrattore su tutti i poligoni. Lo spostamento degli attrattori, influenza ogni poligono Fig. 4.33 Con la stessa modalità, possiamo spostare i poligoni in direzione Z, in base al numero che arriva da <min> o cambiando le funzioni matematiche, se necessario. Quindi l'utilizzo degli attrattori non è solo legato alle dimensioni. Semplice !!!. Possiamo applicare qualunque funzione su questi poligoni, per ruotarli, cambiare il colore, etc. Ma proviamo ora a pensare cosa potrebbe succedere se avessimo due attrattori nel campo. Creiamo un altro cluster, il che significa un altro punto su Rhinoceros associato al <point> e al <circle> su Grasshopper. La prima parte dell'algoritmo risulta la stessa. Ancora una volta, abbiamo bisogno di misurare la distanza tra questo <attractor_2> e il centro del poligono o il <pt_grid> e quindi dividerlo per lo stesso <number slider> qui rinominato <att_power> per controllare la potenza dell'attrattore 69 Fig. 4.34 Introduzione di un secondo attrattore e applicazione dell'algoritmo. Ora abbiamo due diverse liste di dati che includono la distanza del poligono da ogni attrattore. Visto che l'attrattore più vicino può influenzare ancora di più il poligono, dobbiamo trovare quale è più vicino e usarlo come sorgente di azione. Useremo un <min> per trovare quale distanza è minore e di conseguenza quale punto è più vicino. Fig. 4.35 Trovare l'attrattore più vicino. Dopo aver trovato quello più vicino attraverso il componente <min>, il resto del processo continuerà in questo modo. Ora tutti i poligoni, sono influenzati dai due attrattori. Fig. 4.36 E' possibile cambiare nuovamente la posizione degli attrattori e vedere come i poligoni reagiscono di conseguenza. 70 Aggiungiamo altri attrattori, con l'obbiettivo di trovare quello più vicino ad ogni poligono e applicare gli effetti predefiniti. Questo concetto è utile per dialogare con le problematiche di progettazione con un largo numero di elementi di piccola scala. Curva attrattore: progetto del muro Poiché in diversi casi necessitiamo di articolare il campo degli oggetti con attrattori lineari anziché puntuali, completiamo il discorso con un altro esempio, ma in questo caso attraverso una curva usata come attrattore. Il nostro obiettivo è quello di progettare un muro traforato per uno spazio interno, per avere una vista incorniciata verso l'altro lato. Questa parte di lavoro potrebbe essere tagliata da fogli materiali. Nel mio spazio progettuale abbiamo un foglio piano (il muro), due curve e una serie di punti distribuiti casualmente come punti di base per forme di taglio. Abbiamo deciso di generare alcuni rettangoli attraverso questi punti, tagliarli dai fogli per creare un muro traforato. Inoltre vogliamo organizzare i rettangoli attraverso le due curve date in modo che alla fine, non risultino solo dei rettangoli sparsi, ma distribuiti in maniera casuale in base alle curve che hanno un livello di organizzazione in una macro scala ma vengono controllate in micro scala. Ciò di cui abbiamo bisogno è di generare questa serie di punti casuali e spostarli verso le curve, in base alla potenza che ricevono da queste. Ho inoltre deciso di spostare i punti lungo entrambe le curve in modo da non avere bisogno di selezionare quello più vicino. Ora ho bisogno di generare i miei rettangoli oltre questi punti per definire, infine, la dimensione di questi rettangoli in relazione alla loro distanza dagli attrattori. Fig. 4.37 Generazione una lista di punti distribuiti casualmente, e introduzione degli attrattori attraverso due componenti <curve> (Params>Geometry>Curve) nello spazio del foglio. Ho usato un componente <domain> per definire l'intervallo tra lo zero (definito manualmente) e il <number slider> per il range dei punti casule. Abbiamo rinominato il <pt> in <Rnd_Pt_Grid>. 71 Fig. 4.38 Quando l'attrattore è un punto, potete spostare la geometria verso di loro. Ma quando l'attrattore è una curva, dovete trovare un punto relativo sulla curva e spostare la vostra geometria, lungo questo specifico punto. E questo punto deve essere unico per ogni geometria., perchè ci deve essere una sola relazione tra gli attrattori e ogni geometria. Se immaginiamo un attrattore come una calamita, questo potrà attirare la geometria, dal suo punto più vicino all'oggetto. Quindi, fondamentalmente ciò di cui abbiamo bisogno all'inizio è di trovare il punto più vicino al <Rnd_pt_grid> su entrambi gli attrattori. Questi punti sono quelli più vicini agli attrattori, per ogni membro del <Rnd_Pt_Grid> separatamente. Ho usato il componente <Curve CP> (Curve>Analysis>Curve CP) che restituiscono il punto più vicino della curva al mio <Rnd_Pt_Grid>. Fig. 4.39 Per poter spostare i punti verso gli attrattori, ho bisogno di definire un vettore per ogni punto in <Rnd_Pt_Grid>, dal punto al suo punto più vicino sugli attrattori. Poiché ho il punto di partenza e il punto finale del vettore, uso il componente <vector 2Pt>. Il secondo punto del vettore (porta B del componente) è il punto più vicino sulla curva. 72 Fig. 4.40 Ora ho connesso tutti i miei <Rnd_Pt_Grid> ai due componenti <move> per spostarli verso gli attrattori. Ma se uso i vettori che ho creato nell'ultimo passaggio, questo sposterà tutti i punti sulle curve, ma non è quello che voglio. Se guardate il componente <Curve CP> possiede un outpunt che restituisce la distanza tra ogni punti e il punto rilevante più vicino sulla curve. Bene! Non abbiamo bisogno di misurare la distanza dagli altri componenti. Ho appena usato un componente <Function> e l collegato la distanza alla X e un <number slider> alla Y per dividere X/Log/(y) in modo da controllare il fattore di spostamento (La funzione logaritmica modifica la relazione lineare tra le distanza e i fattori risultanti). Ora ho bisogno di modificare la dimensione dei miei vettori, in base ai nuovi fattori creati. Ho bisogno di un componente per modificare la dimensione dei vettori ed è per questo che ho usato un componente <multiply> (Vector>Vector>Multiply) che lo fa per me, quindi ho collegato il <vector 2P> come base di vettori ed ho cambiato la loro dimensione attraverso il fattore dimensione e ho collegato i vettori risultanti al componente <move> che sposta il <Rnd_Pt_Grid> in relazione alla loro distanza dagli attrattori, e verso di loro. 73 Fig. 4.41 Il <number slider> cambia la potenza con cui ogni attrattore sposta gli oggetti verso di loro Fig. 4.42 IL passo successivo è quello di generare dei rettangoli. Ho collegato i punti spostati, usati come punti di base, al componente rettangolo (curve>primitive>rectangle). Ma come già detto, voglio cambiare la dimensione dei rettangoli in base alla loro distanza da ogni attrattore. Ho quindi usato gli stessi valori numerici che ho usato per il modulo del vettore e li ho modificati attraverso due funzioni. Ho diviso questi fattori per 5 sul valore di X dei rettangoli e li ho divisi per 25 nella loro dimensione di Y. Come potete vedere i rettangoli hanno dimensioni diverse, in base alla loro distanza originale dagli attrattori, ma hanno tutti le stesse proporzioni a causa del fattore di divisione applicato. Potete cambiare questo fattore (5, 25) a qualunque valore o usare lo slider per modificarli gradualmente per vedere quale proporzione è quella più delicata per il vostro gusto. 74 Fig. 4.43 Manipolando le variabili otterremo diversi modelli tra i quali potremo scegliere il migliore per i nostri scopi progettuali. Fig. 4.44 Modello del progetto finale di un sistema di muri traforati. I diversi effetti di ombreggiatura possono essere considerati come fattori per controllare la dimensione delle aperture. 75 Capitolo 5_ Spazio Parametrico 76 Capitolo_5_Spazio Parametrico Il nostro studio delle geometria osserva gli oggetti nello spazio, la rappresentazione digitale delle forme e della tettonica, la diversa articolazione degli elementi e i processi multipli di generazione di forme; delle idee classiche di simmetria e pattern fino alle NURBS e alle MESH. Stiamo dunque dialogando con gli oggetti. Questi oggetti possono essere parallelepipedi, sfere, coni, superfici o qualunque loro articolazione. In termini di loro rappresentazione nello spazio, generalmente sono generalmente divisi in punti zero dimensionali , curve monodimensionali, superfici bidimensionali e solidi quali oggetti a 3 dimensioni. Formuliamo lo spazio attraverso un sistema di coordinate per identificare alcune proprietà di base quali posizione, direzione e misure. Il sistema di coordinate cartesiane è uno spazio tridimensionale che ha un punto di origine O=(0,0,0) e tre assi che in questo punto che creano le direzioni X, Y e Z. Ma dovremo considerare che questo sistema tridimensionale di coordinate, include anche sistemi bidimensionali (spazi piatti (x,y)) e monodimensionali (spazi lineari (x)). Ciò che conosciamo come progetto parametrico comunica con questi spazi. Per disegnare curve free form e superfici in maniera parametrica, abbiamo bisogno di andare oltre questi spazi. Visto che il disegno parametrico si sposta tra questii spazi, abbiamo bisogno di capirli come spazi parametrici. 5_1_Spazio parametrico monodimensionale L'asse X è una linea infinita che contiene alcuni numeri associati, occupanti diverse posizioni. Semplicemente X=0 indica l'origine e x=2.35 un punto nella direzione della X positiva che dista 2.35 unità dall'origine. Questa semplice sistema di coordinate monodimensionale può essere parametrizzato con differenti posizioni, ma anche una curva nello spazio contiene la possibilità di essere parametrizzata attraverso una serie di numeri reali che mostrano una differente posizione nella curva. Nel nostro spazio parametrico 1D, quando si parla di punti, questi potrebbero essere descritti attraverso dei numeri reali che sono associati ad un punto specifico in una curva presa in considerazione. La cosa importante da sapere è che, poiché non stiamo lavorando più sull'asse X, ogni curva ha il suo proprio spazio parametrico e questi parametri non combaciano esattamente con il sistema di misura universale. Ogni curva in Grasshopper ha uno spazio parametrico che parte da zero e termina in un numero reale positivo (fig. 5.1) Fig. 5.1. Spazio parametrico monodimensionale di una curva . Ad ogni valore di 't' è associato un numero reale con una posizione nella curva. 77 Quindi parlando di curve e lavorando e riferendoci ad alcuni punti specifici, non abbiamo l'obbligo di confrontarci sempre con punti nello spazio 3D con p=(x,y,z) ma possiamo richiamare un punto su una curva attraverso un parametro specifico p=t. Ed è ovvio che possiamo sempre convertire questo spazio parametrico in un punto in un sistema coordinate generale globali (Fig. 5.2) Fig. 5.2 Spazio parametrico e conversione in unsistema di coordinate 3D 5_2_Spazio parametrico bidimensionale Due assi, X e Y in un sistema di coordinate generale globale, dialogano con i punti di una infinita superficie piatta nella quale, ad ogni punto di questo spazio è associato con una coppia di numeri p=(x,y). Quasi come in uno spazio 1D, possiamo immaginare che tutti i valori di uno spazio 2D possono essere tracciati non solo in un sistema generale di coordinate di una superficie piana, ma anche in ogni superficie spaziale. Quindi possiamo parametrizzare un sistema di coordinate su una superficie curva nello spazio, e nominare i diversi punti attraverso una coppia di numeri qui chiamati spazio UV, nei quali ogni punto P sulla superficie risponde a P=(u,v). Ancora una volta, non abbiamo bisogno di lavorare con tre valori P=(x,y,z) come in uno spazio 3D per trovare i punti, ma, possiamo lavorare con i parametri UV sulla superficie (Fig. 5.3). Fig. 5.3 Spazio parametrico UV e 2D 78 Questi 'parametri' sono specifici per ogni superficie e non sono dei dati generici come il sistema di coordinate globale, ed è per questo che li chiamiamo parametrici! Abbiamo accesso allo spazio 3D e alle coordinate equivalenti per ogni punto sulla superficie (Fig. 5.4) Fig. 5.4. Equivalenza del punto p=(u,v) in un sistema di coordinate generali p=(x,y,z) 5_3_ Transizione tra gli spazi Una parte fondamentale nel pensare un progetto parametrico, è quella di conoscere esattamente di quale sistema di coordinate o di spazio parametrico abbiamo bisogno per poter progettare. Lavorando con curve free form e superfici, abbiamo bisogno di procurarci dei dati per la creazione o la trasformazione di altre geometrie. Con lo scripting risulta più complicato, ma con l'interfaccia visuale di Grasshopper, rispetto al codice, è possibile identificare semplicemente quale tipo di dati necessitiamo per centrare i nostri scopi progettuali. Notiamo che per richiamare una geometria con gli Algoritmi Generativi e Grasshopper, non sempre ciò di cui abbiamo bisogno è un parametro, o un valore in un sistema di coordinate, ma qualche volte abbiamo bisogno solo di un indice numerico. Se stessimo lavorando con un gruppo di punti, linee o quant'altro, e fossero generate come un gruppo di oggetti, come una nuvola di punti, poiché ogni oggetto è associato con un numero naturale che mostra la posizione in una lista di oggetti, avremo solo bisogno di nominare i numeri degli oggetti come indici al posto di un sistema di coordinate. L'indicizzazione dei numeri, come delle serie variabili in programmazione è un sistema di calcolo basato sullo zero. Fig. 5.5 Indicizzare numericamente in un gruppo di oggetti è il modo più semplice di nominarli. Questo è un sistema di calcolo basato sullo zero, significa che i numeri partono da zero. 79 Quindi, come precedentemente menzionato, nella modellazione associativa, generiamo le nostre geometrie passo dopo passo come alcuni oggetti relazionati e per questo motivo usiamo lo spazio parametrico per ogni oggetto, in modo da estrarre informazioni specifiche sullo spazio e usarle come base di dati per i passi successivi. Questa potrebbe partire da un semplice campo di punti come generatori di base e terminare ai dettagli sottili del modello risultante. 5_4_ Componenti parametrici di base 5_4_1 Valutazione di curve Il componente <evaluate> è la funzione che trova i punti su una curva o su una superficie, in base al parametro passato. Il componente <evaluate curve> (Curve>Analysis>Evaluate curve) prende una curva ed un parametro (un numero) e restituisce un punto su una curva in base a questo parametro. Fig.5.6 Il punto valutato su <curve> in base ad un parametro specifico, che proviene da un <number slider> Fig. 5.7 Possiamo usare qualunque <curve> disegnata su Rhinoceroso su Grasshopper perchè venga valutata. E possiamo usare una <series> di numeri come parametrici per <evaluate> al posto di un parametro. Nell'esempio precedente, a causa di alcuni numeri del componente <series> che sono più grandi del dominio della curva, è possibile che il componente <evaluate> restituisce un warning (attenzione!) e diventi arancione poiché i i punti sono posizionati nell'immaginaria continuazione della curva 80 Fig. 5.8 Sebbene l'output 'D' di un componente <curve> restituisca il dominio di una curva (parametri minimo e massimo di una curva) alternativamente possiamo passare una curva esterna (Params>Geometry>curve) e nel suo menu contestuale possiamo scegliere 'reparameterize' (riparametrizza). Questo imposta il dominio della curva in valori compresi tra zero ed uno. Fondamentalmente possiamo dunque scorrere tutte le curve attraverso un <number slider> o insieme numerico compreso tra zero e uno, e non essere preoccupati che i parametri possano andare oltre il dominio numerico della curva stessa. Ci sono altri componenti utili per lo spazio parametrico in Curve>Analysis / division di cui parleremo in seguito 5_4_2 Valutazione di una superficie Se per valutare una curva abbiamo bisogno di un numero come parametro (perchè la curva ha uno spazio monodimensionale) per le superfici abbiamo bisogno di una coppia di numeri come parametri (u,v) mediante i quali possiamo valutare uno specifico punto su una superficie. Possiamo usare il componente <evaluate surface> (Surface>Analysis>Analysis) per valutare un punto su una superficie con un parametro specifico. Possiamo usare un componente <point> per valutare la superficie usandolo come input per UV del componente <evaluate surface> (ignorerà la dimensione Z) e sarà possibile scorre i punti sulla superficie solo con la parte X e Y del punto, quale parametri U e V. 81 Fig. 5.9 Un punto valutato su una superficie, basato sui parametri U e V, provenienti da <number slider>, con un componente <point> che crea una coppia di numeri. Ancora, come con le curve è possibile scegliere il 'reparameterize' sul menu contestuale della superficie e impostare il dominio della superficie compreso tra zero e uno in entrambe le direzioni U e V. Cambiate U e V attraverso un <number slider> e osservate come questi punti valutati si muovono sulla superficie (Ho rinominato gli input X,Y,Z, dei componenti in U e V) Fig. 5.10 poiché abbiamo bisogno di <points> per valutare una <surface> come vedete, possiamo usare ogni metodo che abbiamo trattato per generare. Le nostre opzioni non sono limitate solo ad una coppia di parametri provenienti da un <number slider>, e possiamo scorrere una superficie in tanti modi. Fig. 5.11 Per dividere una superficie (come nell'esempio precedente) in alcune righe e colonne, possiamo anche usare il <divide surface> o, se c'è bisogno di alcuni piani che incrocino alcune righe e colonne di una superficie possiamo usare <surface frame> entrambi dal menu Surface, sotto il pannello Util. 82 5_4_3_ Punto più vicino alla curva e alla superficie Ma non sempre usiamo parametri per cercare i punti, talvolta abbiamo il punto e vogliamo sapere i suoi parametri per altri usi. Questo succede quando entra in gioco la problematica di trovare il punto più vicino. I componenti <curve CP> e <surface CP> (punto più vicino alla curva/superficie) sono due componenti che ci aiutano a fare questo. Fig. 5.12 <Curve Cp> e <Surface Cp> ci aiutano a trovare il parametro di un punto su una curva o su una superficie. Esistono anche altri componenti che è necessario alimentare con altri parametri. 5_5 Proliferazione di oggetti nello spazio parametrico Per diverse ragioni di design, i progettisti usano delle superfici per riprodurci velocemente sopra, altre geometrie. Le superfici sono oggetti bidimensionali flessibili e continui che rappresentano delle basi adatte a questo scopo. Esistono tanti metodi che dialogano con le superficie come la Pannellizzazione. In ogni caso voglio iniziare con uno dei metodi più semplici, mentre degli altri discuteremo più avanti. Abbiamo una superficie free-form e una geometria semplice, come per esempio un parallelepipedo. La domanda ora è: come faccio a riempire la superficie con un certo numero di parallelepipedi, in modo da avere superfici differenziate (come per esempio un involucro), per il quale dobbiamo avere il controllo della macro scala (superficie) e della micro scala (parallelepipedo) separatamente, ma in maniera associativa? Ecco il metodo: per poter portare a termine l'operazione, dovremo dividere la superficie nella parti desiderate e generare i nostri parallelepipedi su queste posizioni specifiche della superficie e rimodificarle in modo da avere manipolazioni locali di questi oggetti. Individuare i posizionamenti desiderati sulla superficie è semplice. Possiamo dividere la superficie o possiamo generare alcuni punti basati su un dato insieme numerico. Per quanto riguarda la manipolazione locale delle geometrie, abbiamo ancora bisogno di set di dati che possono essere usati per le trasformazioni quali rotazione, spostamenti locali, ridimensionamenti, correzioni etc. 83 Fig. 5.13 Una superficie free form riparametrizzata, valutata attraverso un intervallo numerico che parte da zero a uno, diviso per 30 elementi attraverso un <number slider> in entrambe le direzioni U e V (qui possiamo usare <divide surface>, ma ho preferito usare il componente <point> per ricordare che tutte le tecniche per la generazione di punti dal capitolo 2 sono opzioni possibili per il nostro esperimento). Fig. 5.14 Come potete vedere il componente <evaluate> restituisce un 'normal' (normale) e un 'plane' (piano) per ogni punto valutato sulla superficie. Ho usate questi piani o cornici per generare serie di parallelepipedi (<box>) sulla superficie finchè le loro dimensioni sono state controllate attraverso <number slider>. Il componente <box> (Surface>primitive>center box) necessita di un centro per il parallelepipedo e della sua lunghezza in X, Y, Z. Per poter modificale localmente i parallelepipedi, ho deciso di ruotarli. Voglio impostare ll'asse di rotazione parallelo alla direzione U della superficie e in base alla situazione di questa semplice superficie, sceglierò il piano XZ, come base per la loro rotazione (fig. 5.15) 84 Fig. 5.15 Rotazione locale di un parallelepipedo Fig. 5.16 Il componente <rotate> necessita di tre input. Il primo è la geometria, cioè i parallelepipedi. Il secondo elemento è l'angolo di rotazione. Li voglio ruotare con dei valori casuali (è possibile ruotarli gradualmente o in qualunque modo). Voglio quindi genere un gruppo di numeri casuali (<random>) il cui numero sarà pari a quello dei parallelepipedi. Quindi ho usato un componente <list lenght> per capire quanti sono i parallelepipedi e l'ho collegato alla porta N del componente <random> e collegato i valori casuali come angoli di razione al componente <rotate>. Infine, per definire il piano dell'asse, ho generato un <XZ plane> su ogni punto che ho valutato sulla superficie e l'ho collegati al componente <rotate> Per migliorare le performance del processo, prima di generare gli oggetti, non scordate di deselezionare l'anteprima ('preview') 85 Fig. 5.17 Geometria finale Fig. 5.18 Provate a combinare concetti differenti sui vostri progetti. Qui, anziché usare valori casuali per le rotazioni dei parallelepipedi, ho usato un attrattore puntiforme e ho impostate la sua distanza da ogni parallelepipedo come fattore di rotazione e come vedete, i risultati sono mostrati in figura. Queste sono tecniche di manipolazione locale dei parallelepipedi, ma sapete che potete applicare modifiche anche alla scala globale. 86 Uso non uniforme della valutazione Durante un progetto mi è venuto in mente che non c'è motivo di usare una distribuzione uniforme dei punti sua una superficie. Mi sono chiesto se è possibile impostare alcuni criteri e valutare la superficie in base a questo e selezionare posizioni specifiche sulla superficie. Poiché usiamo i parametri U e V, lo spazio e l'insieme di dati incrementali (o loop incrementali nello scripting), mi sono anche chiesto se siamo sempre limitati ad una divisione rettangolare di una superficie. Esistono diversi domande riguardo l'individuazione delle tracce su una superficie, ma qui sto per cimentarmi in un semplice esempio per mostrare come in situazioni specifiche possiamo usare alcuni dei parametri U e V di una superficie per crearci sopra una griglia rettangolare non uniforme. L'esempio delle colonne Ho due superfici free form per coprire uno spazio e sto pensando di creare uno spazio sociale aperto in mezzo. Voglio aggiungere alcune colonne tra le superfici ma, visto che sono free form e e non voglio creare una griglia di colonne, ho deciso di limitare la lunghezza della colonne e aggiungerne il più possibile in determinate posizioni con specifici limiti di altezza. Voglio inserire in questo spazio due coni come colonne, invertiti e intersecati, per creare una forma semplice. Fig. 5.19 Ho inserito due generiche superfici in Grasshopper, attraverso <srf _top> e <srf_bottom> come spazio coperto l'ho riparametrizzato. Ho inoltre generato un intervallo numerico compreso tra zero e uno, diviso attraverso un <number slider> e usando il componente <point> ho valutato queste superfici ai punti. 87 Fig. 5.20 In seguito, ho generato una serie di <line> tra tutti questi punti, ed ho inoltre misurato la distanza tra ogni coppia di punti. Fig. 5.21 Ora ho bisogno di estrarre le mie linee desiderate dalla lista. Ho usato un componente <dispatch> (Sets>List> Dispatch) per selezionare le linee dalla lista. Un componente <dispatch> necessita di dati booleani associati con i dati della lista, per mandare quelli associati a TRUE verso l'output A e quelli associati a FALSE, verso l'output B. I dati booleani arrivano da una semplice funzione di comparazione. In questa funzione ho comparato la lunghezza delle linee con dei numeri dati come lunghezza massima della linea (x>y, x=<number slider>, y=<distance>). Ogni lunghezza di linea minore del <number slider> creano un valore TRUE, attraverso la loro funzione e li passano attraverso il componente <dispatch> all'output A. Quindi se uso le linee provenienti da un output A di <dispatch>, sono sicuro che saranno minori di una certa lunghezza, saranno quindi le mie colonne. 88 Fig. 5.22 La geometria della colonne è composta da due coni invertiti uno rispetto all'altro, che si intersecano nella sommità. Poiché qui ho l'asse delle colonne, voglio disegnare due circonferenze nei punti terminali degli assi e estruderli verso i punti sulle curve, in modo da rendere possibile l'intersezione. Fig. 5.23 Usando il componente <end point> posso avere entrambe le estremità delle colonne. Quindi posso connettere questi punti e usarli come punti base per creare delle circonferenze con un raggio dato. Avete già appreso che queste circonferenze sono piane mentre le nostre superfici non lo sono. Ho quindi bisogno di proiettarle attraverso il componente <project> (Curve>Util>Project) per questo motivo. La parte B di <project> sarà connessa alle superficie inferiore e superiore. 89 Fig. 5.24 L'ultimo passo è quello di estrudere queste circonferenze proiettate verso punti specifici sull'asse della colonna (Fig. 5.23). Ho usato il componente <extrude point> e l'ho quindi collegate alle circonferenze proiettate come curve di base. Per l'estrusione verso un punto, ho collegato tutti agli assi delle colonne al componente <curve>, li ho riparametrizzati, quindi valutati in due parametri specifici distanti 0.6 dalla cima e 0.4 dalla parte inferiore. Fig. 5.25 Sebbene in questo esempio ho usato ancora il tracciamento basato sulla griglia su una superficie, ho usato ulteriori criteri per scegliere alcuni punti e non tutti in maniera uniforme. 90 Fig. 5.26 Modello finale L'idea di usare spazi parametrici delle curve e delle superfici per proliferare oggetti sulle stesse superfici, comporta diverse opzioni e metodi. Non fermatevi ad uno solo, ma provatene diversi. Vediamo ancora qualcos'altro. 5_6_Alberi di dati Parlando di spazi parametrici e usando i componenti relativi, è ora di aprire un nuovo capitolo riguardo l'amministrazione dei dati su Grasshopper, chiamato 'data tree' (albero dei dati) che, poco alla volta, potrebbe servirvi quando lavorate con modelli complessi, specialmente nello spazio parametrico di curve e superfici. Le grandi potenzialità degli algoritmi generativi consentono di creare e governare centinaia di oggetti tra loro associativi. Lavorando con un grande numero di oggetti, talvolta abbiamo bisogno di applicare dei comandi a tutti gli oggetti contemporaneamente e, talvolta, abbiamo bisogno di estrarre un elemento a cui applicare un comando. Abbiamo quindi bisogno di avere accesso ai nostri oggetti e gestire i nostri dati (oggetti) in maniere differenti. Immaginiamo di avere 5 curve nel nostro spazio progettuale e doverle dividere in 10 parti. Ora vogliamo estrarre tutti i secondi punti su queste curve e connetterli insieme con una curva interpolata. 91 Fig. 5.27 Il componente <curve> importa 5 curve dentro Grasshopper, tutte divise in 10 parti. Se selezioniamo l'indice numerico 1 attraverso il componente <item> dai punti di divisione, vedrete che non verrà selezionato solo il secondo punto della prima curva, ma tutti quelli che hanno indice 1 (cioè tutti i secondi punti di tutte le curve)Bene! Ma se colleghiamo questi punti ad un componente <interpolate>, per disegnare una curva, vedrete che il componente mostrerà un errore e non disegnerà niente. Per capire il problema, introduciamo un componente molto utile e osserviamo la situazione. Questo componente è il <param viewer> da Params>Special. Compariamo i risultati Fig. 5.28 Il componente <param viewer> mostra all'interno del componente informazioni interessanti sui dati, che ci fanno capirela ragione dell'errore del componente. Ciò che vedete in <param viewer> è il concetto del data tree in Grasshopper. Come si evince dalla figura 5.28, il componente <curve> contiene 5 elementi, ma mentre queste curve sono divise e generano alcuni punti per ogni curva, i punti sono elencati in una lista di dati differenti, chiamati 'Rami' (branches). Questo significa che il risultato del componente <divide> non è solo una lista di dati contenente 55 punti, ma ora abbiamo cinque liste di dati ognuna con 11 punti all'interno. Questo significa che il tree (albero) è stato diviso in branches (rami) in modo da facilitare usi futuri e renderli accessibili in maniera più semplice nei nostri progetti. Perciò, quando selezioniamo <item> indice 1, vengono selezionati gli elementi di indice 1 di ogni lista 92 Fig. 5.29 <param viewer> con l'opzione 'data tree' attivata dal menu contestuale, il cui compito è di mostrare la differenza tra i rami di dati in ogni componente. Chiediamoci ora perchè il componente <interpolate> non disegna una curva: dov'è il problema? Diamo un'occhiata ravvicinata alle informazioni tratte dalla nostra situazione. Fig. 5.30 <Param viewer> e <Panel> di A: curve e B: selezioni dei punti di indice 1 93 Nella prima immagine della figura 5.30 <Param Viewer> del componente <curve> mostra uno dei rami principali. Se date un'occhiata al suo pannello, vedrete che c'è una lista di curve sotto il titolo di {0}. Qui in Grasshopper la notazione { } rappresenta il simbolo dell'albero dei dati, e mostrano i rami in cui sono posizionati gli oggetti. Quindi tutte le curve nella prima immagine sotto {0} sono situate nel ramo principale. Se tornate indietro alla fig. 5.28 vedrete che i <param viewer> per le curve indicano (Paths=1) che significa che abbiamo un solo ramo di dati e in questo ramo {0} (N=5) abbiamo 5 elementi. Ma nella seconda immagine della Fig. 5.30 possiamo vedere che i dati nel componenti <item> inseriti nella lista sotto 5 diversi rami e quando vengono trasferiti dentro un <interpolate>, sono separati l'uno dall'altro e il componente <interpolate> non può disegnare le polilinea attraverso 5 punti separati. Come possiamo risolvere il problema? Fig. 5.31 Per risolvere il problema ho usato il componente <flatten> (Sets>Tree) che, come dice il nome, converte i dati da ramificazioni multiple in un unico ramo, visibile in <param viewer>. Come potete vedere nel secondo <panel> ora abbiamo 5 punti sotto il ramo {0} e il componente <interpolate> può disegnare una polilinea attraverso questi cinque punti. Per riassumere il concetto dobbiamo capire che, lavorando con oggetti multipli a livelli differenti, i dati si dispongono in una struttura gerarchica in rami, e ogni ramo di dati ha il proprio percorso e indice numerico che mostra il suo indirizzo univoco del ramo (p.e. {0;1}). E' importante sapere che lavorando con i componenti che gestiscono le liste, questi dovranno sottostare alle regole lavorando su ogni ramo come se fossero liste separate. Potremo avere bisogno, inoltre, sia di generare rami di dati per conto nostro sia far convergere le ramificazioni di dati in un unico flusso, o altri trattamenti dei dati. Negli esperimenti successivi ho provato a mettere in pratica queste situazioni. 94 Fig. 5.32 Ramificazione di dati su un 'data tree' Per concludere con questa tematica, vediamo un altro esempio. Il nostro scopo è quello di progettare una superficie forata come quella schizzata in fig. 5.33 basata su una data superficie. Il processo sarà affrontato in maniera veloce per vedere subito il risultato finale. Fig. 5.33 Schizzo della superficie desiderata. Per disegnare questa superficie forata, voglio generare tante piccole linee nel bordo superiore e inferiore della superficie e unirle attraverso un loft. Questo creerà tante piccole superfici che, tutte 95 insieme, daranno l'idea della mia superficie forata. Dovrei fare attenzione alla direzione delle linee per poter controllare le graduali modifiche delle superfici e quindi del risultato finale. Fig. 5.34 Ho introdotto una generica <surface> nel canvas e l'ho esplosa attraverso <Brep Components> (Surface>Analysis>Brep Components) per avere accesso ai suoi bordi. Quindi ho selezionato i bordi superiori ed inferiori con <item> attraverso l'indice 0 e 2. Fig. 5.35. Ho applicato una distanza di offset al bordo inferiore e ho anche modificato la direzione del bordo superiore con <flip> (Curve>Util>Flip) perchè so che i due bordi non hanno la stessa direzione. A questo punto ho usato il componente <divide> per dividere questi bordi e avere un insieme di punti da gestire (Possiamo anche usare un solo componente <divide> ma ora preferiscono non renderlo più complesso). 96 Fig. 5.36 Il componente <line> è stato usato per connettere i punti della parte inferiore ai punti che stanno sulla curva distanziata dal bordo inferiore. Un altro componente <line> è usato per connettere tutti i punti appartenenti al bordo superiore con il loro punto successivo della lista (shift offset=1) Fig. 5.37 Se ora uso i componenti <line> per fare un loft, vedremo che viene generata una superficie, ma non quella che voglio io. Anche l'utilizzo del componente <wave> non aiuta. 97 Fig. 5.38 Se guardiamo il <param viewer> dei componenti <line>, vedremo che entrambi hanno un solo ramo di dati e quindi il loft non è stato applicato a coppie separate di linee, ma ad un unico blocco. Chiaramente voglio che le linee vengano inserite in liste differenti per essere trattate come dati singoli e quando usate per il loft, diventino coppie di linee. Fig. 5.39 Per risolvere questo problema ho usato un componente molto utile, il <Graft> (Sets>Tree>Graft Tree>. Come potete vedere, come risultato abbiamo che le liste di dati in entrambi i componenti <line> sono stati divisi in rami, un ramo per ogni elemento della lista. Ora il componente <loft> può creare la superficie da ogni linea della prima lista di dati ad una linea associata nella seconda lista di dati. A questo punto possiamo vedere che il risultato è la geometria schizzata in precedenza. Qui, a differenza del primo esempio, dobbiamo ordinare i nostri dati in rami differenti per poter geometrie multiple come risultato , altrimenti avremo avuto una sola superficie continua. 98 Fig. 5.40 Vi ricordo che se volete disegnare una curva interpolata passante per punti specifici, provenienti da una superficie valutata, dobbiamo 'spianare' la lista di dati con il componente <flatten>, creando un ramo di dati per i punti e passarli alla curva interpolata. Questo perchè tutte queste superfici sono inserite in rami diversi così come i punti valutati. Dobbiamo dunque capire che in componenti diversi e situazione progettuali, dobbiamo processare i dati in uno o più rami. I componenti che ci possono aiutare, li troviamo in Sets>Tree Fig. 5.41 Modello finale della superficie. 99 CAPITOLO_ 6_Deformazioni e Morphing 100 6_1_Deformazioni e Morphing La geometria non è sempre fatta di oggetti puri. Per poter realizzare alcuni tipi di progetti, abbiamo bisogno di cambiare le porzioni e le condizioni generali dei volumi e di altri prodotti geometrici. La deformazione e il morphing sono tra le funzioni più potenti nel campo del design free form. Attraverso le deformazioni, possiamo torcere, inclinare, piegare le geometrie e attraverso il morphing possiamo trasformare le geometrie da una condizione limite all'altra. Diamo un'occhiata ad una deformazione semplice. Se abbiamo un oggetto, come la Sfera, sappiamo che esiste un parallelepipedo limite (gabbia) attorno, la cui manipolazione deforma l'intera geometria. Fig. 6.1 Deformazione di un oggetto attraverso il parallelepipedo limite. In base al tipo di trasformazione (se fatta attraverso un angolo, spostamento etc), possiamo chiamarla inclinazione, piegatura o deformazione libera. Per ogni funzione di deformazione, potremo avere bisogno dell'intero parallelepipedo limite, o solo uno dei suoi lati come piano oppure uno dei suoi punti. Se controllate i diversi componenti per le deformazioni, potrete facilmente trovare la il costruzioni geometriche di base per ottenere la deformazione. Nel campo dell'animazione il termine morphing indica il processo di transizione da un'immagine ad un'altra in maniera leggera e scorrevole. I componenti di Morphing in Grasshopper, lavorano allo stesso modo. Per esempio qui il componente <Box Morph> (Xform>Morph>Box Morph) deforma un oggetto attraverso un parallelepipedo di riferimento (Parallelepipedo limite), in un parallelepipedo destinazione (target box), mentre il componente <Surface morph> lavora con una superficie di base sulla quale è possibile, nel dominio specificato, deformare le vostre geometrie e l'altezza dell'oggetto. Nella scheda Xform troverete <Box Morph>, <Surface Morph> e altri componenti aggiuntivi che possono provvedere alla raccolta di dati. Considerato che abbiamo diversi comandi che deformano un parallelepipedo, se usiamo questi parallelepipedi deformati come parallelepipedi di bersaglio, allora possiamo deformare ogni geometria in Grasshopper attraverso la combinazione del componente Box Morph. Come vedete in figura 6.2, abbiamo un oggetto importato su Grasshopper attraverso il 101 componente <geometry>. Questo oggetto è inscritto in un parallelepipedo limite che ho disegnato io solo per migliorare la visualizzazione. Ho inoltre disegnato un altro parallelepipedo con valori inseriti manualmente. Fig. 6.2 L'oggetto iniziale (sfera) e il parallelepipedo impostato manualmente. Fig. 6.3 Un componente <Box morph> (Xform>Morph>Box Morph) deforma un oggetto da un parallelepipedo di riferimento ad un parallelepipedo di bersaglio. Visto che ho un solo oggetto, l'ho collegato sia come geometria che come parallelepipedo di riferimento (in caso di più geometrie potete usare il componente <Bounding box> (Surface>Primitive>Bounding box>)). Ho deselezionato l'anteprima del <box> per vedere meglio la geometria trasformata. 102 Fig. 6.4 Ora, cambiando la dimensione del parallelepipedo bersaglio potete vedere la geometria modificata. Fig. 6.5 Qui possiamo vedere che al posto di un parallelepipedo, se produco una serie di parallelepipedi posso iniziare a modificare i miei oggetti con il Morph più di una volta. Come vedete, i parallelepipedi differenzianti attraverso il componente <series> nella loro dimensione Y, provocano differenziazioni negli oggetti modificati. 6_2_ Pannelizzazione Una delle applicazioni più comuni del morphing è la pannellizzazione. Questa idea proviene dalla divisione di una superficie free form in piccole parti, specialmente a scopo produttivo. Sebbene le superfici free form sono largamente usate nell'industria automobilistica, non è facile trasferirle in campo architettonico per gli usi su scala maggiore. I vantaggi della pannallizzazione sono quelli di dividere una superficie in piccole parti (chiamate componenti) rendendo più semplice il processo di fabbricazione e il trasporto, rendendoli anche più controllabili in termini di precisione finale del prodotto. E' inoltre possibile, talvolta, dividere una superficie curva in piccole parti piatte e quindi ottenere la curvatura totale dall'assemblaggio delle geometrie piane che possono essere prodotte da fogli di materiale. Ci sono diversi motivi che riguardano la dimensione, la curvatura, le regolazioni etc, di cui proveremo a discutere. 103 Iniziamo con una superficie semplice ed un componente come modulo per pannellizzare la superficie. Fig. 6.6 Una generica superficie a doppia curvatura pronta per la pannellizzazione. Fig. 6.7 IL componente che voglio usare per popolare la superficie....niente di speciale, solo un esempio. Fig.6.8 Prima di tutto ho bisogno di importare la superficie e l'oggetto da ripetere come componente di Grasshopper. Facendo riferimento ai componenti disponibili in Grasshopper, possiamo generare diversi parallelepipedi sulla superficie e usarli come oggetti di bersaglio, ed applicargli modulo trasformato. Ho quindi importato un <box morph> e ho usato il modulo come geometria e come parallelepipedo limite. Ora ho bisogno di generare il parallelepipedo bersaglio per fare il Morph del componente. 104 Fig 6.9 Il componente di cui ho bisogno per creare il parallelepipedo bersaglio, è <surface box> (Xform>Morph>Surface Box). Questo componente genera parallelepipedi sopra una una superficie, in base all'intervallo indicato dal dominio della superficie e all'altezza del parallelepipedo. Gli ho quindi connesso la superficie e il risultato sarà il bersaglio per il componente <box morph>. Ho bisogno di di definire il dominio dei parallelepipedi, oppure dividere l'intervallo numerico della superficie nelle sue direzioni U e V, per creare i parallelepipedi. Fig. 6.10 Per poter dividere il dominio della superficie, ho usato <divide interval2> che dice al <surface box>, quante divisioni in U e V sono necessarie. Un altro <number slider>, definisce l'altezza del parallelepipedo bersaglio, cioè dei componenti trasformati. Quindi fondamentalmente l'idea è semplice. Creiamo un modulo (un componente) e disegniamo la nostra superficie. Quindi generiamo la quantità di parallelepipedi sopra questa superficie (come parallelepipedo bersaglio) e quindi morfizziamo il modulo dentro parallelepipedi. Dopo questo passaggio, sarà possibile modificare il numeri di elementi in entrambe le direzioni U e V e cambiare anche il modulo e avere sempre un aggiornamento dinamico sulla superficie. 105 Fig. 6.11 Superficie finale creata con il nostro modulo. 6_3_Manipolazioni di micro livello Sebbene sia fantastico gestire un modulo su una superficie, potrebbe sembrare che questo sia un modo generico di progettare. Sappiamo che possiamo modificare il numero dei moduli, o cambiare il modulo stesso, ma il risultato sarà una generica superficie e non avremo un controllo locale del nostro sistema. Sto quindi pensando di creare un sistema basato sui componenti con cui potremo avere maggior controllo e permettere di progettare superfici generiche che non rispondono a nessuno criterio di micro scala. Per poter introdurre il concetto, partiamo prima con un esempio semplice, per poi procedere verso uno più pratico. Abbiamo usato l'idea degli attrattori per applicare manipolazioni locali ad un gruppo di oggetti. Sto pensando di applicare lo stesso metodo per progettare un sistema basato sui componenti con manipolazioni locali date da un attrattore. L'idea è quella di cambiare la dimensione del componente (in questo caso l'altezza) in base agli effetti di un punto attrattore. 106 Fig. 6.12 Diamo un'occhiata agli ingredienti: una superficie a doppia curvatura importata attraverso un <base_srf>, un cono importato come <component> in Grasshopper, un <divide interval2> per la divisione della superficie, e un <bounding box> come parallelepipedo di riferimento. Più tardi, cambiando la dimensione del parallelepipedo limite, potrò cambiare la dimensione di tutte i miei componenti sulla <base_Srf> grazie al cambiamento del parallelepipedo di riferimento. L'input altezza del componente <surface box> richiede l'altezza del parallelepipedo nel dato intervallo. L'idea è quella di usare altezze relative al posto di quelli costanti. Quindi, al posto di numeri, potremo creare della relazioni tra le posizioni di ogni parallelepipedo e i punti attrattori e generare numeri diversi come altezze associativa. Ciò di cui ho bisogno ora è di misurare la distanza tra ogni parallelepipedo e l'attrattore. Il problema tecnico è che ancora non c'è alcun parallelepipedo generato, quindi ho bisogno di un punto sulla superficie, che diverrà poi centro di ogni parallelepipedo, per misurare la distanza. Fig. 6.13 Qui ho usato lo stesso <divide interval2> che voglio usare per <surface box>, per un componente <isotrim> (Surface>Util>Isotrim). Questo componente divide la superficie in subsuperfici. Attraverso queste sub-superfici posso usare un altro componente <Brep Area> (Surface>Analysis>BRep area) per usare il sottoprodotto di questo componente, cioè il 'Centroide dell'area' per ogni sub-superficie. Ho misurato la distanza tra questi punti (centroidi) dagli <attractor> per usarla come fattore di riferimento per l'altezza del parallelepipedo bersaglio nel componente <surface box> 107 Fig. 6.14 Ora ho diviso la distanza misurata con un numero preso dal un <number slider> per controllare l'effetto dell'attrattore e ho usato il risultato come input per l'altezza, in modo da generare parallelepipedi bersaglio con il componente <surface box>. La superficie proviene da <base_Srf>, il <divide_interval2> restituisce il dominio della superficie, mentre l'altezza è data dalla relazione tra la posizione del parallelepipedo e dell'attrattore. Come vedete, le altezze dei parallelepipedi sono differenti, in base alla posizioni del punto <attractor>. Fig. 6.15 Per la parte rimanente, connettete il <component>, i parallelepipedi scalati e la <surface box> al componente <morph box> che produrrà i componenti sulla superficie. Cambiando il fattore di scala, potete cambiare la dimensione di tutti i componenti e come sempre, la posizione degli attrattori, sarà controllabile manualmente. 108 Fig. 6.16 Modello finale Come vedete, la dimensione dei componenti inizia ad accettare manipolazioni locali, basate su proprietà esterne che sono i punti attrattori. Sebbene l'idea sia basata su un semplice attrattore, il risultato potrebbe essere interessante e l'idea è quella di mostrare che possiamo differenziare i parallelepipedi ed ottenere risultati diversi. Ora sappiamo che il concetto di morphing e di pannellizzazione non sono necessariamente generici. Avendo provato il concetto, proseguiamo con un altro esperimento pratico. 6_4_ Modulazione reattiva Per il nostro esperimento progettuale, l'idea è quella di modulare una superficie data con un controllo su ogni modulo, che significa che ogni modulo di questo sistema deve rispondere ad alcuni determinati criteri. Quindi ancor più della differenziazione locale dei moduli, qui voglio avere un controllo specifico sul mio sistema, attraverso dei dati criteri che possono essere ambientali, funzionali, visuali o ogni altro comportamento associativo a cui vogliamo che il nostro modulo risponda. Nel prossimo esempio, per poter rendere l'involucro di un edificio, reattivo all'ambiente in cui si trova, voglio usare un sistema che risponde in base alla luce solare. Nei vostri esperimenti, la variabile, potrebbe essere il vento, la pioggia o le funzioni interne o ogni altro criterio di cui avete bisogno, nonché la combinazione di questi. Ho qui una superficie semplice come l'involucro di un edificio che voglio coprire con due diversi tipi di componenti. Il primo è chiuso e non permette la penetrazione della luce solare, mentre l'altro ha delle aperture. Questi componenti dovrebbero proliferare sull'involucro in base alla direzione principale della 109 luce solare nel sito. Ho usato un angolo definito dall'utente per dire all'algoritmo che per una determinato grado di incidenza delle luce solare dovremo avere un componente chiuso, e per gli altri, uno aperto. La definizione di Grasshopper non contiene niente di nuovo, ma il concetto mi permette di creare della variazioni sull'involucro invece di creare una superficie generica. Fondamentalmente quando la superficie è di tipo free form, si muove e ha diversi orientamenti, la luce solare la colpisce da entrambe le direzione per diversi gradi di incidenza. In base alla differenza di angolo tra la superficie e la luce solare, questa variazione nel componente avviene nel sistema Fig. 6.17 Primi schizzi del modulo reattivo su un sistema di facciata Ingredienti: Fig. 6.18 Superficie esterna di un edificio come involucro che dobbiamo pannellizzare 110 Fig. 6.19 I due diversi tipi di componenti per la pannellizzazione Fig. 6.20 Il primo passo è simile a quello precedente. Ho introdotto una <surface> e ho usato <divide interval2> per dividerla nelle direzioni U e V. Ho generato dei parallelepipedi bersaglio attraverso <surface box>. Ho anche usato <isotrim> con lo stesso intervallo dei parallelepipedi per trovare la posizione degli stessi sulla superficie e ho inserito un <Brep area> per trovare il centroide di questa area (selezionata in verde). Allo stesso tempo ho usato un componente <curve> per importare l'angolo principale della luce solare del sito e con i suoi <end points> ho creato un <vector 2pt> che specifica la direzione della luce solare. Potete manipolare e cambiare questa curva per vedere l'effetto della luce solare sui componenti nelle diverse direzioni. Come potete vedere dalla prima immagine, c'è una superficie – l'involucro - divisa in parti per generare i componenti ed è presente anche un vettore per la luce solare. Voglio conoscere l'angolo tra questo vettore e la superficie nella posizione di ogni componente. Devo avere un unico risultato per il calcolo dell'angolo e il modo migliore è quello di usare la normale alla superficie che è unica per ogni punto. Una normale è un vettore perpendicolare alla superficie in un punto specifico, Posso quindi usarlo per controllare l'angolo per ogni componente. 111 Fig. 6.21 Per poter valutare l'angolo tra la luce solare e la superficie, voglio misurare questo ancolo tra la luce solare e la normale alla superficie nella posizione di ogni componente. Posso quindi decidere per ogni intervallo di angoli, che tipo di componente può andare bene. Quindi, dopo aver generato i punti centrali, ho bisogno delle normali alla superfici e usare questi parametri per <evaluate> la superficie in questi punti per poter avere le normali delle superficie in questi punti. Fig. 6.22 Ora ho usato un componente <angle> (Vector>vector>angle) per valutare l'angolo tra la direzione del sole e la facciata. Ho quindi convertito questo angolo in gradi e ho usato una <function> per vedere se questo angolo è più grande del <max angle> oppure no. Questa funzione (x>y) restituisce dati booleani: TRUE per gli angoli più piccoli, e FALSE per quelli più grandi 112 Fig. 6.23 In base ai dati booleani provenienti dalla comparazione degli angoli, ho creato un componente <dispatch> che spedisce i dati che sono i parallelepipedi bersaglio (Ho diversi parallelepipedo bersaglio, come punti centrali e normali, quindi posso usare il parallelepipedo al posto dei punti). Quindi ho diviso in miei parallelepipedi bersaglio in due gruppi differenti in cui la differenza è l'angolo che ricevono dalla fonte luminosa. Il resto dell'algoritmo è semplice e simile a quello precedente. Ho solo bisogno di morfizzare i miei componenti in un parallelepipedo parallelepipedo bersaglio, che qui sono due diversi. 113 Fig. 6.24 Ho qui introdotto due componenti diversi come geometria unica ed ho usato due componenti <morph box>, ognuno associato con una parte dei dati spediti (con <dispatch>) per generare i componenti <C_close> o <C_Open> sulla facciata. Fig. 6.25 Se ora guardiamo da più vicino, potremo vedere che le diverse parti della facciata e in base alla sua curvatura e direzione, genera diversi tipi di componenti. Fig. 6.26 Modello finale. La biforcazione del parallelepipedo bersaglio (e dei componenti) potrebbe essere più complessa e non composta da solo due algoritmi. Dipende dal nostro progetto e dai criteri utilizzati. 114 Possiamo pensare ad una facciata basata sui componenti, nella quale alcuni di loro sono chiusi e altri sono aperti. Quelli aperti hanno delle parti regolabili che sono orientate rispetto a delle forze esterne e riflettono anche le funzioni interne dell'edificio e così via. Potete vedere che l'idea è quella di avere un controllo sulla micro scala sul sistema e permette progettazioni generiche. Ed è anche chiaro che abbiamo ancora un controllo globale (la superficie) e locale (i componenti). 115 CAPITOLO 7 Superfici NURBS e Mesh 116 7_1 Superfici NURBS parametriche Nel capitolo precedente, abbiamo fatto diversi esperimenti con le superfici trattando lo strumento Loft per la loro creazione. Abbiamo anche usato superfici NURBS free form. In molti casi la generazione delle superfici dipende da altre geometrie di base, come le curve o i punti. All'interno di Grasshopper, esistono diversi componenti per generare queste geometrie, e per chi di voi ha un minimo di esperienza nella modellazione tradizionale con Rhinoceros, questi dovrebbero essere noti. Le superfici geometriche sembrano essere il prodotto finale del nostro progetto, in quanto rappresentano facciate, muri, etc ed è per questo che abbiamo bisogno di tanta lavoro per generare dati come punti e curve che ci servono come geometrie di base. Ho qui deciso di disegnare un edificio in maniera schematico e molto semplice, solo per indicare che i numerevoli componenti di Grasshopper hanno il potenziale di disegnare diversi oggetti con delle semplici costruzioni. So che il processo progettuale da solo potrebbe non essere soddisfacente, ma qui voglio solo concentrarmi sull'uso dei nuovi componenti. Torre parametrica Nell'area portuale del Tamigi a Londra, vicino al Canary Warf, dove possono essere costruiti edifici molto alti, ci sono le potenzialità per costruire delle torri. Ipotizziamo di crearne uno insieme, in maniera veramente semplice e schematica solo per testare alcuni delle idee di base per lavorare con superfici free form. Diamo un'occhiata all'area Fig. 7.1 Vista dell'area, Canary Warf, Londra (immagine: www.maps.live.com, Microsoft Virtual Earth). Il sito che ho scelto per il progetto è nella sponda del Tamigi, con una vista molto prestigiosa sul fiume e vicino alla piazza di ingresso dell'area centrale di Canary Warf (Westferry Road). Non voglio essere troppo specifico sul sito, quindi diamo giusto un'occhiata al luogo dove sto per proporre il progetto e continuiamo con le tematiche geometriche. 117 Fig. 7.2 Area per la proposta di Torre. Disegno a mano Esistono diversi modi per iniziare questa bozza. Posso disegnare il piano terra e copiarlo in alto, iniziare a manipolarlo e aggiungere dettagli. Ho deciso di usare alcuni componenti per le superfici, quindi la tecnica potrebbe non essere appropriata ma lo scopo è quello di espandere i nostri esperimenti, anche perchè sono sicuro che avete già cercato sul web e avuto già in mente diverse idee progettuali per lavorare sulla torre in maniera associativa. L'idea che ho in mente non è ben definita, ma so che la mia torre avrà una superficie generale di vetro, coperta da alcuni elementi lineari in facciata. Visto che non mi piace progettare una torre convenzionale, voglio anche avere alcuni spazi cavi nel suo involucro esterno, sparsi lungo la facciata. Questi volumi dovrebbero intersecarsi con gli elementi lineari in modo da tagliarli. Voglio anche disegnare uno spazio pubblico vicino al fiume e connetterlo alla torre con gli stessi elementi della facciata, in moda da creare una continuità dalla torre verso l'ansa del fiume. Come vedete in figura 7.3 ho disegnato le mie curve di base manualmente su rhino. Queste curve corrispondono con le specifiche del sito, per le limitazione nell'altezza e per la forma e bordi del. La prima curva è stata disegnata e quindi specchiata nell'angolo successivo e ancora specchiata per quello successivo e così via. Altre due curve sono state disegnate come bordi dello spazio pubblico, che partono da terra e quindi salgono fino ad essere paralleli ai bordi della torre. Tenete conto che queste sono curve sperimentali e che otete disegnare qualunque cosa vogliate e andare avanti per la parte mancante. 118 Fig. 7.3 Linee di base per il sito della torre Elementi di base per la facciata Fig. 7.4 come primo passo, ho importato queste quattro curve in Grasshopper attraverso un componente <curve> e le ho quindi divise con <divide curve> in 40 parti come i piani della torre. Come vedete, i punti risultanti dalla divisione sono ordinati in differenti rami di dati. Fig. 7.5 Ora devo disegnare le curve di base con questi punti di divisione, per realizzare gli elementi della facciata stessa. Voglio disegnare linee dai punti di divisione per ogni curva, fino al punto corrispondente della curva successiva. Per fare ciò, ho usato un <explode tree> rinominandolo <Bang!> (Sets>Tree>Explode tree) per accedere ai diversi rimani separatamente. Ho aggiunto delle 119 linee da tutti i punti dei rami a quelli successivi. Fig. 7.6 In questo step ho aggiunto gli spazi cavi per la facciata, con una distribuzione casuale. Sono degli ellissoidi importanti tutti insieme su Grasshopper con il componente <geometry>. Ho inoltre unito tutte le linee generate precedentemente, tramite il componente <merge>. Fig. 7.7 In questo passo ho tagliato (componente <trim>), e unito (<merge>) le linee con queste geometrie. Il componente <trim> restituisce le parti tagliate all'interno e all'esterno dell'area di taglio. Qui ho usato la parte esterna. Ho estruso queste parti come gli elementi lineari della facciata. 120 Fig. 7.8 Questa è una curva chiusa che connette quattro lati della pianta della torre. Visto che ho bisogno di creare superfici differenti, ho esploso la curva (<explode>) per ottenere i segmenti e ho inoltre usato <graft> per generare un ramo per ogni curva. Poiché ho una sezione planare e due curve di bordo che definiscono il imite della facciata per ogni lato, voglio usare il componente <sweep 2> per creare la superficie di facciata con lo sweep a 2 binari. Fig. 7.9 Ho inserito un componente <sweep 2> per generare le superfici di facciata. Ho usato le curve planari innestate con <graft> come curve di sezione per lo sweep. I binari saranno i bordi delle curve. Il componente <receiver> è connesso alle curve di bordo. Le ho quindi innestate (<graft>) una volta e spostate (<shift>) e ancora innestate (<graft>) per generare tutte le prime e le seconde curve di binario associate alle curve planare di sezione. !!Nota: se non ottenete lo stesso risultato dell'immagine, l'ordine della curve di bordo (binari) non è associato correttamente all'ordine delle curve planari (curve di sezione) e dovete quindi cambiarne l'ordine delle curve di bordo nella lista, o manualmente riassegnandole al 121 componente <curve> in ordine diverso oppure spostando la lista in Grasshopper Fig. 7.10 In questo passo voglio sottrarre gli spazi cavi <Geo> dalla facciata precedentemente generata. Poichè la direzione delle normali delle superfici è fondamentale per questo comando, ho invertito (<Flip>) le normali della superfici e il risultato è la superficie principale con il <Geo> che è stato rimosso. Fig. 7.11 Con lo stesso procedimento, ho importato entrambe le curve dello spazio pubblico, le ho divise, esplose e disegnato tra loro altre linee. Posso connettere questi componenti <line> allo stesso componente <extrude> quale elemento di facciata per generare geometrie identiche. Fig. 7.12 Dopo le generazione delle geometrie, cucinate (bake) i componenti <differnce> e <extrude>. 122 Fig. 7.13 Bozza finale del modello. 123 7_2_ Topologia e Geometria Fino ad ora abbiamo usato diversi componenti e lavorato con superfici NURBS. Ma, come già detto, esistono altri tipi di superfici che in altri contesti, risultano utili. Non sempre vogliamo ottenere la bellezza e la dolcezza delle NURBS, ma potremo avere bisogno di un controllo più preciso, di processi più semplici o equazioni più facili. Oltre la classica superficie di rivoluzione, righe o tubi, abbiamo diverse superfici free form come quelle di Bezier, o le B-Spline. Tratteremo ora la tematica delle mesh, che rappresentano un altro tipo di superficie. Le mesh rappresentano un altra tipologia di superfici free form, composte di piccole parti (facce)la cui accumulazione crea l'intera superficie. Non esiste quindi alcuna funzione matematica interna o nascosta che generi la forma della superficie, la quale viene invece definita dall'insieme delle facce. Osservando le mesh, concentriamoci sulle facce. Queste possono essere triangolari, rettangolari o esagonali. Guardandole più attentamente, possiamo vedere la griglia di punti che le crea. Questi punti sono elementi di base della superficie mesh. Ogni piccolo gruppo di questi punti (per esempio ogni tre nelle mesh triangolari) creano una faccia, che con il resto della geometria diventa una superficie. Questi punti sono connessi tra di loro da linee dritte. Ci sono due concetti fondamentali che riguardano le mesh: la posizione di questi punti e la loro connessione. La posizione dei punti è collegata alla geometria delle mesh e la connessione dei punti è collegata alla topologia. Geometria vs Topologia Mentre la geometria ha a che fare con la posizione degli oggetti nello spazio, la Topologia riguarda la loro relazione. Matematicamente parlando, la topologia rappresenta le proprietà degli oggetti che le trasformazioni e le deformazioni non possono modificare. Quindi per esempio una circonferenza ed un'ellisse sono topologicamente identiche, e hanno solo differenze geometriche. Osserviamo la fig. 7.14. Come vedete ci sono quattro punti connessi tra loro. Nella prima immagine, entrambi A e B hanno la stessa topologia perchè hanno la stessa relazione tra i loro punti (stessa connessione). Sono però geometricamente diversi a causa dello spostamento di un punto. Nella seconda immagine la geometria dei punti è la stessa mentre la loro connessione è diversa e non sono topologicamente equivalenti. Fig. 7.14 Topologia e Geometria Il concetto di topologia è molto importante per le mesh. Ogni faccia in un oggetto mesh, ha dei punti angolari e questi punti sono connessi l'uno con l'altro con un identico ordine per tutte le facce dell'oggetto mesh. Possiamo quindi applicare ogni trasformazione ad un oggetto mesh e spostarne i vertici in uno spazio anche se non uniformemente, ma la connessione dei vertici 124 dovrebbe essere preservata per preservare le facce, altrimenti crollerà. Fig. 7.15 Entrambe le superficie rosse e grigie sono mesh con le stesse facce e vertici. In quella grigia i vertici sono spostati, creando una diversa configurazione geometrica delle mesh, ma la connettività delle mesh non cambia ed entrambe le superfici sono topologicamente uguali. Sappiamo dunque l'importanza degli aspetti topologici nelle mesh, le quali sono geometrie molto potenti fin tanto che abbiamo diversi punti e abbiamo bisogno di un tipo di superficie per rappresentarli come spazio continuo. Possiamo applicare alle mesh diversi tipi di algoritmi che lavorano con i punti poiché ne preservano la topologia. Per esempio, usando elementi finiti di analisi o applicazioni specifiche come dynamic relaxation, e sistemi particellari, è più semplice lavorare con le mesh che con altri tipi di superfici poiché la funzione può lavorare con i vertici delle mesh. Le mesh sono semplici da migliorare e veloci da lavorare ma possono contenere dei buchi e delle discontinuità nella loro geometria. Ci sono tanti algoritmi per rifinire le mesh e creare delle superfici più lisce. Poiché facce differenti possono avere inizialmente diversi colori, le mesh sono buone per la rappresentazione a scopi di analisi (per colore). Nella scheda 'Mesh' possiamo trovare diversi componenti che lavorano con questo tipo di geometria. 7_3_Mesh Ho un gruppo di punti e voglio creare, attraverso gli stessi, una superficie. In questo esempio il gruppo di punti è semplificato in una struttura a griglia. Sto pensando ad una griglia verticale che rappresenti i parametri di base di una superficie, la quale è sottoposta all'effetto di un vento immaginario. Voglio quindi spostare questi punti in base al fattore vento (o rispetto ad ogni forza che può essere rappresentata da un vettore), e rappresentare la superficie deformata risultante. Quindi, cambiando il fattore del vento, possiamo vedere come il risultato di questa superficie reagisca di conseguenza. 125 Fig. 7.16 Il primo passo è semplice. Usando un componente <series> con un numero di punti gestito dallo slider <N_pt>e una distanza tra loro definita da <distance_pt> (ancora uno slider), ho generato una griglia di punti creati con il riferimento incrociato. La pressione di questo vento immaginario, influenza tutti i punti della griglia. Facciamo però finta che la forza del vento aumenti quando andiamo in alto, quindi la pressione del vento aumenta con valori di Z più alti. Allo stesso tempo, la forza del vento, influenza i punti interni più dei punti vicini ai bordi. I punti sul bordo della sezione piana non si muovono per niente (punti fissi). Fig. 7.17 Diagramma del vento che influenza la superficie. A: sezione; effetto verticale della forza, B: pianta; effetto orizzontale. Fondamentalmente ho bisogno di due diversi meccanismi per modellare questi effetti, uno per il diagramma in sezione, e un altro per la pianta. Ho semplificato le equazioni solo per imitare il modo in cui vogliamo che le forze agiscano. Per questo primo meccanismo impostiamo una semplice equazione matematica; ho usato (X^2) dove X è il valore di Z del punto sottoposto alla 126 forza. Quindi per ogni punto ho bisogno di estrarre le coordinate di Z del punto. Per semplificare il tutto, ho fatto finta che la direzione della forza sia quella della Y, rispetto al sistema globale delle coordinate. Quindi per ogni punto della griglia, ho bisogno di generare un vettore nella direzione Y e ho impostato la forza attraverso il numero che ho ricevuto dalle coordinate Z del punto. Per il secondo diagramma abbiamo bisogno di qualcosa di più di un'equazione. Diamo un'occhiata alla prima parte. Fig. 7.18 Coordinate Z dei punti estratti attraverso il componente <decompose> e quindi attivati da una funzione X^2 e divise per un numero passato da un <number slider> per controllare il movimento generale. Il risultato è un fattore che moltiplica (<multiply>) il vettore forza (Vector>vector>Multiply) che è un semplice vettore <unit Y> rispetto al sistema globale. Fig. 7.19 Spostando i punti con questi vettori potete vedere la griglia di punti risultanti che soddisfa il primo passo di questo processo. Vediamo ora la seconda parte delle forze descritte: nella sezione planare i punti sui bordi rimangano fissi, mentre i punti nel mezzo si spostano più degli altri. La Fig. 7.20 mostra questo spostamento per ogni riga della griglia dei punti. 127 Fig. 7.20 Spostamento dei punti in riga (vista planare). Poiché per ogni punto ho i vettori forza, devo controllarli e impostare ancora una volta il valore, per essere sicuro che il loro spostamento nella sezione planare incontri anche il secondo criterio. Quindi per ogni riga di punti nella griglia voglio generare una fattore che controlli il modulo del vettore. Qui ho assunto che, per i punti nel mezzo, i vettori forza saranno al massimo, mentre per i punti sui bordi diventano zero, cioè uno spostamento nullo. Gli altri punti un valore di forza e quindi di spostamento intermedio. Fig. 7.21 Per il secondo meccanismo, ho bisogno di un <range> compreso tra e 0 e 1 da applicare ad ogni punto. 0 per il bordo e 1 per il centro. Ho bisogno dunque di un range da 0 a 1 spostandomi dal bordo al centro e uno che varia da 1 a 0 dal centro al bordo. Ho bisogno che questo componente <range> generi valori in quantità pari al numero di punti per ogni riga. Ho impostato il <N_pt> in modo da generare solo numeri pari e li ho divisi per 2, quindi ho sottratto 1 (perchè il componente <range> prende i numeri di queste divisioni e non i numeri dei valori). Vedete che il primo <panel> nostra 4 numeri compresi tra 0 e 1 per la prima metà dei punti. Ho quindi invertito una lista e l'ho collegato all'altra. Come vedete nel secondo pannello, ho generato una lista da 0 a 1 a 0 e i il numeri dei valori nella lista è lo stesso dei numeri dei punti in ogni riga. L'ultimo passo è quello di generare questi elementi per tutti i punti nella griglia. Ho quindi duplicato (<duplicate>) i punti in quantità pari a <N_pt> (i numeri delle righe e delle colonne sono gli stessi). Ora ho un fattore per tutti i punti della griglia, basato sulla loro posizione nella loro riga. 128 Fig. 7.22 Ora ho bisogno di moltiplicare (<multiply>) ancora i vettori forza per i nuovi fattori. Se sposto i punti con questi nuovi vettori, possiamo vedere come due differenti meccanismi agiscano sull'intera griglia di punti. In realtà, questa parte di esempio necessita di un'analisi più attenta. I metodi come quelli di Particle Spring Systems (Sistemi di particelle a molla) o Finite Element Analysis (Analisi degli elementi finiti) usano il concetto che tutti i vettori influenzano i punti dell'insieme e i punti si influenzano l'uno con l'altro. Quindi, quando applicate le forze tutti i punti vengono influenzati e questi punti si influenzano l'uno con l'altro simultaneamente. Questo processo dovrebbe essere calcolato in loop iterativi, in modo da calcolare la posizione di riposo dell'intero sistema. Qui voglio solo fare un semplice esempio senza questi effetti, e voglio solo mostrare una semplice rappresentazione di un tipo di sistema che dialoga con forze multiple. Ho usato equazioni matematiche molto semplici, che nella realtà sono un po' più complicate! L'idea riguarda la rappresentazione mesh del processo, quindi vediamo la parte relativa alla generazione di mesh Mesh Fig. 7.23 Generazione delle mesh. Ora potete semplicemente aggiungere un componente <mesh> (Mesh>Primitive>Mesh) nel canvas e connettere tutti i punti che sono stati spostati ai suoi vertici: vedrete che nella scena non succede niente. Abbiamo bisogno di definire la facce della geometria mesh da generare. Le facce delle mesh sono serie di numeri che definiscono il modo in cui i punti 129 sono interconnessi per creare delle facce per ogni superficie. Quindi i vertici sono parti geometriche delle mesh, ma ora abbiamo bisogno della definizione topologica delle mesh, per poterle generare. Ogni 4 punti angolari della griglia, si definisce una faccia del quadrante per l'oggetto mesh. Se guardiamo alla griglia di punti, vedremo che ci sono degli indici numerici per ogni punto della griglia. Conosciamo ogni punto attraverso il suo indice, e sappiamo che questo sostituisce le coordinate in modo da poter dialogare con la sua topologia. Fig. 7.24 Indice numerico dei punti nella griglia Per definire le facce della mesh, abbiamo bisogno di etichettare i 4 punti angolari che riteniamo essere una faccia, mettergli insieme e passargli il componente <mesh> in modo da creare la superficie. Fig. 7.25 In una data griglia di punti, una semplice quadrante viene definito attraverso una sequenza di punti che, connessi mediante una curva, creano una faccia. La curva parte da un punto della griglia, si muove verso il punto successivo, quindi su quello della riga successiva, torna indietro di una colonna rimanendo sulla stessa riga, e si chiude tornando al primo punto. Vediamo che la prima faccia, nella sua definizione è composta dai punti [0,1,6,5]. La seconda faccia ha [1,2,7,6] e così via. 130 Per definire le facce dell'intera mesh, dovremo trovare la relazione tra questi punti e quindi creare un algoritmo che generi la regola per la creazione della facce. Se guardiamo la matrice delle faccia, vediamo che per ogni prima primo punto, possiamo definire il secondo come quello successivo nella griglia. Quindi, per ogni punto (n) nella griglia, il punto successivo sulla faccia è (n+1). Semplice! Andando avanti, sappiamo che si sposta sempre di una riga: quindi se aggiungiamo il numero delle colonne (c) all'indice (n) del punto, potremo ottenere il punto nella seconda riga (n+c). Quindi, per esempio, nel suddetto esercizio, abbiamo 5 colonne (c=5) e per il punto (1) il punto successivo della faccia della mesh è (n+c) cioè il punto (6). Quindi per ogni punto (n) come primo punto, il terzo sarà (n+1+c). Ci siamo! L'ultimo punto, è sempre localizzato un una colonna dietro il terzo punto. Quindi, per ogni punto (n+1+c) come terzo punto, il punto successivo sarà (n+1+c-1) il che significa (n+c). Quindi per esempio, per il punto (6) come terzo punto, il punto successivo diventa (5) Riassumendo: per ogni punto (n) nella griglia, la faccia che inizia da questo punto singolo avrà come punti nella lista dei vertici la seguente combinazione : [n,n+1,n+1+c,n+c] dove (c) è il numero di colonne nella griglia. Fig. 7.26 Dopo aver definito tutte le facce della mesh, la superficie può essere generata. Guardando i vertici della mesh, vediamo che c'è ancora qualcosa da considerare. Se ricordate l'esempio del 'Triangolo' del capitolo 3, avevamo trattato il problema della selezione dei punti che potevano essere considerati 'primo punto' della griglia. Se guardiamo la griglia dell'esempio appena trattato, vedremo che i punti dell'ultima colonna e dell'ultima riga non possono essere punti di partenza per le facce. Quindi oltre all'algoritmo per generare facce, abbiamo bisogno anche un po' di maneggiare i dati per generare i primi punti dell'intera griglia e passare questi primi punti all'algoritmo e quindi generare le facce delle mesh. Fondamentalmente, nella lista di punti, dovremo omettere i punti dell'ultima riga e dell'ultima colonna e quindi iniziare a generare la faccia matrice. Per generare la lista di facce, abbiamo bisogno di generare una lista di numeri come indici dei punti. 131 Fig. 7.27 Generazione di un indice numerico dei primi punti nella griglia con un componente <series> . Il numero dei valori delle serie, deriva da Npt> come numero delle colonne (alcune come righe) a attraverso l'utilizzo della funzione <x*(x-1)> voglio generare una serie di numeri come <columns*(rows-1) per generare l'indice per tutti i punti nella griglia omettendo l'ultima riga. Il passo successivo è quello di selezionare (<cull>) l'indice della lista attraverso il numero di colonne (<N_pt>) per eliminare l'indice dei punti anche nell'ultima colonna. Fig. 7.28 Indice numerico finale del possibile primo punto della faccia mesh nella griglia (con 8 punti in ogni colonna). 132 Fig. 7.29 Il componente <mesh quad> (Mesh>Primitive>Mesh quad) ha il compito di generare le facce. Ho collegato la lista dei primi numeri al primo punto del <quad> Ora è il momento di generare la lista di indici per le facce. Fig. 7.30 Mentre (n) è l'indice del primo punto e (c) è il numero delle colonne, il secondo punto sarà (n+1), il terzo ((n+1)+c) (l'indice del secondo punto più il numero delle colonne), e l'ultimo punto sarà ((n+1+c)-1) (l'indice del terzo punto meno 1). 133 Fig. 7.31 La mesh risultante. 7_4 Analisi cromatica Per concludere l'esempio, diamo un'occhiata a come possiamo rappresentare la nostra mesh finale, attraverso l'uso dei colori come strumento di analisi. Ci sono diversi componenti in Grasshopper che ci danno una rappresentazione cromatica e questi colori sono adeguati per i nostri scopi di analisi. Nell'esempio, ancora per mostrare meglio il concetto, ho ipotizzato che alla fine vogliamo vedere il valore di deviazione della nostra superficie finale dal punto iniziale (superficie verticale). Voglio applicare un gradiente di colori che parta dai punti che rimangono fissati al il fondo colorandosi fino ai punti che hanno il valore massimo di deviazione dalla posizione verticale con il più alto colore del gradiente. Semplicemente, per trovare la quantità di deviazione, ho bisogno di misurare lo stato finale di ogni punto dal suo stato originale. Quindi posso usare questi valori per assegnare il colore alle facce della mesh in base alla loro distanza. Fig. 7.32 Tornando indietro ho il punto iniziale della griglia generato nel primo passaggio e ho inoltre lo spostamento finale che ho usato per generare i vertici della mesh. Posso usare un componente <distance> per misurare la distanza tra la posizione iniziale dei punti e la loro posizione finale per vederne la deviazione. 134 Fig. 7.33 Per i nostri scopi analitici, voglio usare un componente <gradient> (Params>special>Gradient) per assegnare un gradiente di colore alla mesh. Ho collegato i valori <distance> all'input (t) di <Gradient> e l'ho collegato all'input colore (c) della mesh. Ma per completare il processo, ho bisogno di definire il limite inferiore e superiore del range del gradiente (L0 e l1). Il limite inferiore è il valore minimo nella lista mentre limite superiore è il valore massimo: gli altri valori sono divisi nei gradienti intermedi. Per avere i valori inferiori e superiori della lista delle deviazioni, ho bisogno di ordinare i dati e ottenere il primo e l'ultimo valore del range numerico. Fig. 7.34 Usando un componente <sort> per ordinare le distanze, ottengo il primo elemento della lista di dati (index=0) come limite inferiore e l'ultimo (indice = <list lenght> -1) come limite superiore del set di dati (valori di deviazione) per connettere il componente <gradient> per assegnare i colori in base al loro range. 135 Fig. 7.35 Cliccando sulla piccola icona colorata nell'angolo del componente <gradient> possiamo cambiare i colori dei gradienti. Fig. 7.36 Cliccando con tasto destro sul componente, sul menu contestuale avrete più opzioni per manipolare il vostro oggetto risultante e diversi tipi di gradienti colorati per soddisfare le rappresentazioni grafiche per l'analisi. 136 Fig. 7.37 Diverse soglie di gradienti. 7_5 Manipolazione delle mesh come metodo progettuale. In base agli oggetti e agli scopi della modellazione, personalmente preferisco ottenere la mesh attraverso la manipolazione di semplici geometrie, invece che generare le mesh partendo da una bozza fino alla definizione del set di punti e alla faccia matrice che non sempre risultano semplici semplice. Attraverso la manipolazione, possiamo usare un semplice oggetto mesh, estrarre i suoi componenti e modificarli e quindi ancora fare una mesh con svariati vertici e facce. Non ho quindi bisogno di generare punti come vertici e matrici di facce. Diamo un'occhiata a questo semplice esempio. Fig.7.38 In questo esempio ho usato un componente <mesh plane> e ho estratto i suoi dati usando un <mesh component> per aver accesso ai suoi vertici e facce. Ho quindi spostato i vertici lungo la direzione Z con dei valori casuali attivati da un <number slider> a ancora l'ho collegato ad un componente <mesh> per generare altre mesh. Ho inoltre usato un componente <cull pattern> (seleziona pattern) ed ho omesso alcune delle facce delle mesh originali e le ho quindi usate come nuove facce per creare altre mesh. La mesh risultante ha differenze geometriche e topologiche dalla sua mesh iniziale e può essere usato per altri scopi di design. L'idea di manipolare geometricamente i vertici e cambiare topologicamente le facce presenta tante diverse possibilità che possono essere usate negli esperimenti progettuali. Poiché le mesh possono trascurare alcune delle loro facce rimanendo sempre una superficie, l'idea di creare una superficie permeabile può essere perseguita in modi diversi. 137 Fig. 7.39 Risultato di mesh manipolate (solo una situazione casuale) Fig. 7.40 Bozze di mesh manipolate. Triangolazioni 138 Fig. 7.41 Esempio di componenti triangolati Ci sono tanti componenti sotto il pannello 'Triangulation' nella scheda Mesh, che contengono utili algoritmi come il Delaunay o il Voronoi o il Convex hull. Questi algoritmi interni possono essere utili per disegnare oggetti complessi e, cosa più importante, questi possono usare insiemi di punti per generare le loro geometrie. Non voglio approfondire la questione, anche perchè questi componenti sono molto semplici da esplorare e potete trovare tantissimi esempi on-line. 139 CAPITOLO_8_ Fabbricazione 140 Capitolo_8_ Fabbricazione Oggigiorno c'è un interesse crescente nella pratica della manifattura assistita dal computer e sulla fabbricazione digitale. A causa dei cambiamenti e delle nuove mode nel processo di design, sembra essere diventata una scelta cruciale e uno dei 'must', quello di spostarsi all'interno del territorio della fabbricazione digitale. Ogni decisione progettuale nello spazio digitale, può essere testata in scale differenti per mostrare l'abilità di fabbricazione e assemblaggio. Poiché è ovvio che questo nuovo processo progettuale e gli algoritmi non rientrano nella tradizionali tecniche di costruzione, i progettisti provano ora ad usare le moderne tecnologie di fabbricazione e adattano i loro prodotti progettuali per venire incontro a queste necessità. Dal momento in cui le macchine CNC hanno iniziato a servire l'industria delle costruzioni fino ad adesso, si è instaurata una grande relazione tra il progetto digitale e la fabbricazione fisica. Sono stati inventati tanti macchinari e sviluppate tante tecnologie per poter svolgere questo tipo di operazione. Allo scopo di progettare e fabbricare elementi di edifici, necessitiamo di avere una conoscenza concisa del processo di fabbricazione per i diversi tipi di materiali e saper preparare i nostri progetti allo scopo. In base agli oggetti che progettiamo, ad i materiali usati, alle logiche di assemblaggio, trasporto, scala etc, abbiamo bisogno di dati opportuni dai nostri progetti e ottenere i risultati desiderati per far funzionare i macchinari. Se i metodi tradizionali nella realizzazione dei progetti richiedevano piante, sezioni e dettagli, oggi, abbiamo bisogno di dati e codici da trasferire alle macchine per realizzare i progetti. Il punto è dunque che i designer devono essere coinvolti nel 'rifornimento' dei dati richiesti, poiché questa fase è strettamente legata con l'oggetto progettuale. I designer qualche volta dovrebbero tenere conto dei riscontri della preparazione dei dati per la fabbricazione per le correzioni del progetto. Talvolta l'obiettivo del designer dovrebbe cambiare per tener conto dei limiti dei macchinari o dell'assemblaggio. Fino a qui, già conosciamo le diverse potenzialità che propone Grasshopper nella modifica dei progetti, e queste variazioni di design potrebbero essere agevolare la fabbricazione, al pari degli altri criteri usati. Voglio aprire l'argomento e toccare alcuni punti in relazione alla fase di preparazione dei dati, per dare un'occhiata alle possibilità di estrazione di dati dai progetti di design per la fabbricazione. Sappiamo che questo argomento è aperto a diverse tecniche, macchinari, materiali etc. 8_1_ Datasheet Allo scopo di preparare i dati per realizzare un oggetto, talvolta abbiamo semplicemente bisogno di una serie di misure, angoli, coordinate o genericamente, dati numerici. Ci sono diversi componenti all'interno di Grasshopper per computare misure, distanze, angoli etc. Il punto importante è la corretta e precisa selezioni dei punti di cui abbiamo bisogno per indirizzarli ad uno scopo preciso. Dovremo essere attenti ad ogni complessità geometrica che che il nostro progetto presenta, in modo da scegliere la posizione desiderata per la misurazione. Il passo successivo è quello di trovare le posizione che ci diano i dati corretti per le nostre produzioni ed evitare di generare numeri che potrebbero risultare dei mangia tempo senza utilità. Alla fine abbiamo bisogno di esportare i dati dal software 3D ai fogli di calcolo e talvolta abbiamo bisogno di manipolare questi dati in base alle esigenze. 141 Progetto fatto con strisce di carta Per continuare a investigare queste tematiche, le strisce di carta mi sembrano un'ottima soluzione. Per capire la logica dell'assemblaggio, ho iniziato con semplici combinazione per il primo livello e ho provato ad aggiungere semplici combinazioni insieme al secondo livello di assemblaggio. All'inizio è stato interessante, ma si è capito subito che non avrei ottenuto i risultati previsti. Alla fine ho provato ad essere più preciso per confrontarmi con la geometria complessa. Fig. 8.1 Strisce di carta: primo esempio Nel passo successivo ho provato ad iniziare con una semplice situazione per capire la logica geometrica e usarla come base per la modellazione digitale. Ho assunto che, attraverso l'uso del modello digitale non sarei stato capace di fare un modello fisico ed ero sicuro che avevo bisogno di fare dei test con la carta per i primi passi. Il mio obiettivo era quello di usare tre strisce di carta e connetterle insieme: una al centro e altre due ad entrambi i lati rispetto a quella centrale, ma con una lunghezza maggiore e ristretti nella parte finale. Questo potrebbe essere il modulo di base da ripetere e generare assemblaggi più grandi. Fig. 8.2 Semplice combinazione di strisce di carta per capire le connessioni e la logica. 142 Modellazione digitale Voglio modellare le strisce di carta digitalmente dopo aver capito le basi del modello fisco. Dal punto di partenza ho bisogno di una semplice curva mediana, che funga da base del progetto. Questa deve poter essere divisa e i punti di divisione devono poter essere selezionati (attraverso i valori booleani TRUE/FALSE dati da un <cull pattern>): i punti che rispondo al valore TRUE devono essere mossi perpendicolarmente alla curva centrale e devono essere usati (sia quelli spostati che quelli rispondenti al FALSE) come vertici per due curve interpolate che posso modellare in maniera simile a quelle che ho descritto con le strisce di carta . Fig. 8.3 Primo metodo di modellazione con la striscia centrale e le curve interpolate come strisce laterali. Ma così sembra troppo semplice e lineare. Ho quindi deciso di aggiungere una differenziazione di dimensione graduale nei punti di connessione in modo da far risultare una geometria un po' più complessa. Ora andiamo su Grasshopper e continuiamo la nostra discussione sulla modellazione. Voglio provare a descrivere in maniera succinta la definizione e andare verso la parte relativa ai dati. Fig. 8.4 Il componente <curve> è la striscia centrale, rappresentata su Rhinocerosda una semplice curva. L'ho riparametrizzata e ora voglio valutarla in intervalli decrescenti. Ho usato un componente <range> e l'ho collegato ad un componente <graph mapper> (Params>Special>Graph mapper) per generare i parametri di valutazione. Un <graph Mapper> (mappatore grafico) rimappa un set di numeri in tanti modi diversi, attraverso la scelta di un particolare tipo di grafico. Come vedete, ho valutato la curva con <graph mapper> con il grafico tipo parabola e i punti risultanti nella curva sono chiari. Potete cambiare il tipo di grafico per modificare la mappatura del range 143 numerico (per ulteriori informazioni visita l'help del componente). Dopo questo ho valutato questi parametri sulla curva iniziale (ho connesso <receiver> con la <curve>). Fig. 8.5 Dopo aver rimappato i dati numerici e valutato i punti, voglio trovare i punti centrali ogni due punti del set precedente. Devo quindi trovare i parametri delle curve, tra ogni punto di base e quello successivo, da valutare. Poiché ho i parametri di ogni primo punto, ho spostato (<shift>) i dati per trovare i punti successivi. Ho inoltre usato un <cull> con la frequenza data dalla lunghezza della lista (<list lenght>) per escludere l'ultimo elemento della lista principale in modo da avere gli stessi elementi come la lista spostata. Il componente <function> trova il parametro intermedio (f(x)=(x+y)/2). Potete vedere i parametri risultanti essere valutati (il <receiver> connesso con <crv>). Fig. 8.6 Ora voglio spostate il punto medio e creare dei vertici deviati della striscia laterale. Questi punti devono sempre spostarsi in una direzione perpendicolare alle curva centrale. Quindi per poterli spostare, ho bisogno di vettori, perpendicolari alla curva centrale nella posizione di ogni punto. Con il componente <evaluate> ottengo anche un vettore tangente ad ogni punto ma abbiamo bisogno di quello perpendicolare. Sappiamo che il prodotto vettoriale di due vettori è ancora un vettore, sempre perpendicolare ad entrambi (Fig. 8.7). Per esempio il vettore unitario Z, potrebbe essere il prodotto vettoriale dei 144 vettori unitari X e Y. La nostra curva centrale è una curva planare quindi sappiamo che il vettore Z in ogni punto della curva sarà sempre perpendicolare al piano della curva. Il vettore tangente ad ogni punto della curva, è situato anch'esso nel piano della curva. Quindi se trovo il prodotto vettoriale del vettore tangente e del vettore unitario Z di ogni punto, il risultato dovrebbe essere un vettore perpendicolare alla curva intermedia che appartiene sempre al piano della curva. Ho usato la tangente del punto dal componente <evaluate> e il vettore <unit Z> per trovare il loro <Xprod> (prodotto vettoriale) che so essere perpendicolare alla curva anche se la modifico manualmente. Altro trucco! Ho usato i valori di <graph mapper> come fattori di potenza di questi vettori Z, in modo da aumentare il movimento dei punti. Quindi, maggiore sarà la distanza tra i punti, più grande sarà il loro spostamento. Fig. 8.7 Prodotto vettoriale. Il vettore A e B sono nel piano di base. Il vettore C è il prodotto vettoriale di A e B ed è perpendicolare al piano di base e di conseguenza ai vettori A e B. Fig. 8.8 Ora ho i punti di base (i primi punti valutati) e i punti spostati. Li ho intrecciati (<weave>) insieme per avere una lista ordinata di dati. Ora se uso questi punti per generare una curva interpolata, potrete vedere la curva di base della striscia laterale. 145 Fig. 8.9 Usando un componente <mirror curve> (Xform>Morph>Mirror curve) posso specchiare la curva interpolata usando la curva intermedia connessa al <receiver>. In questo modo avrò quindi entrambi i lati con strisce di carta modulate sullo stesso concetto Fig. 8.10 Se ora connetto la curva intermedia e le curve laterali ad un componente <extrude> posso vedere la mia prima combinazione di strisce di carta, con uno spazio vuoto decrescente tra i punti. Fig. 8.11 Posso iniziare a modificare la strisce intermedia e vedere come Grasshopper aggiorna le tre strisce di carta che sono connesse l'una con l'altra, o posso modificare i valori degli slider e controllare la geometria risultante per selezionare quello più vicino al modello fisico. 146 Dopo aver trovato la configurazione per le mie strisce di carta, ho bisogno di estrarre le dimensioni e i posizionamenti per costruire il mio modello basato su questi dati. Sebbene sia facile modellare tutte queste strisce su fogli di carta e tagliarle con il laser, qui voglio creare un processo più generale ed ottenere i dati iniziali necessari in modo da non essere limitato ad una specifica macchina e ad uno specifico metodo di manifattura. Potete usare questi dati come generici codici per la produzione. Facendo un semplice modello di carta so che ho bisogno della posizione dei punti di connessione sulle strisce ed è ovvio che questi punti di connessione avranno una lunghezza diversa nella striscia sulla parte sinistra rispetto alla striscia della parte destra nonché rispetto a quella intermedia. Quindi se ottengo la lunghezza di divisione da Grasshopper, possono segnarla sulle strisce. Poiché le strisce sono curve il componente <distance> non mi aiuta per questa misura. Ho bisogno di una distanza tra un punto a un'altro o dal punto iniziale della striscia ma rispetto alla curva, in modo che quando lo uso sulla carta stesa mi possa dare la posizione corretta. Per ottenere questa lunghezza ho bisogno di trovare i parametri dei punti di connessione sulle strisce (curve) e valutare la loro posizione. Gli stessi componenti mi restituiranno la distanza di questi punti da un punto iniziale della curva. Fig. 8.12 Come vedete ho usato il primo gruppo di punti valutati che ho chiamato punti della curva principale (main curve points) nelle striscia centrale (curva iniziale). L'output L del componente mi restituisce la distanza dei punti (punti di connessione) dal punto di partenza della striscia per la striscia intermedia. Ho anche usato questi punti per trovare i loro parametri su un lato della curva. Ho quindi usato un componente <curve cp> per trovare i parametri di ogni punto sulla curva (t). Questi parametri sono stati utilizzati per valutare la curva e trovare la loro distanza dai punti iniziali. Vorrei fare lo stesso per la parte successiva delle striscia. Assicuratevi che la direzione di tutte le curve sia la stessa e controllate dov'è il punto di partenza della curva (origine della misurazione). 147 Esportazione di dati Fig. 8.13 Cliccate con il tasto destro sul componente <panel> e selezionate 'stream content'. Con questa opzione sarete in grado di salvare i vostri dati in diversi formati ed usarli come generici dati numerici. Qui li ho salvati con un semplice formato .txt per poterli usare in Microsoft Excel. Fig. 8.14 Su un foglio di Excel, cliccate su una cella vuota e selezionate la scheda Data sotto 'Get External Data' . Scegliete a questo punto 'from text'. Selezionate il file salvato in txt dal percorso in cui l'ho avete posizione e seguite le istruzioni di Excel. Questi passi vi permetteranno di amministrare diversi tipi di dati riguardanti, per esempio, come dividere i vostri dati in diverse celle e colonne etc. 148 Fig. 8.15 Ora potete vedere i vostri dati posizionati su un foglio di calcolo di excel. Potete fare lo stesso per le strisce rimanenti Fig. 8.16 Tavola delle distanza dei punti di connessione lungo la striscia. Se avete una lista di coordinate 3D di punti e le volete esportare su Excel, avete diverse opzioni a disposizione. Se esportate le coordinate 3D con il metodo sopra descritto, vedrete che ci sono tante parentesi e virgole non necessarie che dovrete cancellare. Potete anche aggiungere delle colonne cliccando sul tasto import text su excel e mettere in altre colonne le virgole e le parentesi per poi cancellarle ancora. 149 In alcuni casi raccomando di decomporre i punti nei loro componente ed esportarli separatamente. Non è gran problema esportare tre liste di dati anziché una. Fig. 8.17 Usando il componente <decompose> per avere le coordinate X, Y e Z in maniera seperata per poi esportarle in questo modo verso un foglio di calcolo. Vi raccomando fortemente di lavorare in maniera professionale con Excel o altri fogli di calcolo, perchè ci aiutano nella gestione dei dati. Con la modellazione ci siamo! Ho usato i dati procurati per segnare le mie strisce di carta e connetterle insieme e creare dei semplici modelli. Per provare anche a me stesso, ho fatto questo processo a mano, per dimostrare che la fabbricazione non necessariamente significa macchine da taglio laser ma, come ha detto un volta Achim Menges (Tutor AA di EmTech), qualche volta il CAM può essere sostituito dal HAM cioè Manifattura Manuale (Hand Aided Manifacturing!!! Giusto per ridere). Ho passato un'ora a tagliare tutte le strisce mentre il processo di assemblaggio ha preso un po' più di tempo ma è stato comunque fatto a mano. 150 Fig. 8.18 Progetto finale di strisce di carta. 151 8_2 Tagli laser e manifatturazione basata sul taglio Per fabbricare geometrie complesse oggigiorno viene usata comunemente l'idea di tagliare fogli di materiali attraverso il laser. Esistono diversi modi in cui possiamo usare questa possibilità per fabbricare oggetti. I tagli laser vanno bene per oggetti costruiti con superfici sviluppabili o piegate. E' possibile distendere su un piano una geometria digitale e semplicemente ritagliarla da un foglio e piegare il materiale per costruirla. Per le geometrie complesse, può anche risultare appropriato ridurle in pezzi separati di superfici piane: l'intero modello può essere disassemblato in diverse parti separate, annidate in fogli piani e possono essere aggiunte le parti sovrapposte per le connessione (incollaggio per esempio) e per il taglio al fine di un assemblaggio fisico. E' anche possibile fabbricare oggetti a doppia curvatura con questo metodo. Sono stati fatti diversi esperimenti per trovare le diverse sezioni di un oggetto a forma di 'blob'. Queste sezioni tagliano l'oggetto in almeno due direzioni e una volta assemblate, vengono unite (solitamente imbrigliate) a creare la forma della gabbia del modello. Poiché gli incisori laser sono degli strumenti generici, ci sono vari metodi, ma per tutti la cosa importante è trovare il modo per ridurre la geometria ad elementi piatti in modo da tagliarla da un foglio di materiale (non importa se carta o metallo, cartone o legno) e alla fine assemblarli insieme. Dei i diversi modi discussi qui, voglio testarne uno su Grasshopper. Sono sicuro che potrete facilmente sperimentare gli altri per conto vostro Fabbricazione di superfici free form Ho deciso di fabbricare una superficie free form per fare esperimenti, preparando e nidificando i pezzi degli oggetti free form da tagliare e tutte le altre cose di cui abbiamo bisogno. Fig. 8.19 Qui abbiamo la superficie che importata su Grasshopper attraverso il componente <geometry>. Questo per mostrare che è possibile introdurre ogni geometria che avete progettato o usare ogni oggetto di Grasshopper che avete generato. Nervature delle sezioni Per poter fabbricare queste forme free form generiche, voglio creare le sezioni di questa superficie, annidarle su un foglio e preparare i file per essere tagliati con un incisore laser. Se l'oggetto su cui state lavorando ha un certo spessore che potete tagliare, il modello è piatto, avete quindi bisogno di aggiungere uno spessore per tagliare le parti. 152 Fig. 8.20 Nel primo passo ho usato un componente <bounding box> (parallelepipedo limite) per trovare l'area su cui voglio lavorare. Ho usato anche un componente <Box corners> (Surface>Analysis>Box corner) per trovare gli angoli opposti del parallelepipedo e usarli come limite del range che voglio per generare le nervature lungo la geometria. Quindi grazie al calcolo della lunghezza e dell'altezza del parallelepipedo, ho potuto usare questi valori come domini che voglio dividere attraverso un componente <range>. Fondamentalmente, usando un <number slider>, posso dividere la lunghezza e l'altezza del parallelepipedo nelle parti desiderate. Fig. 8.21 Il mio obiettivo è di generare piani accanto la lunghezza e larghezza del parallelepipedo in quantità pari a quella delle nervature di cui ho bisogno. Prima di tutto ho generato due piani, uno <xy plane> e l'altro <xz plane>:il primo perpendicolare alla lunghezza del parallelepipedo e il secondo perpendicolare alla larghezza. Ho generato entrambi nel primo vertice del parallelepipedo connettendoli all'output A del <box corner>. Ora posso generare i vettori <unit X> e <unit Y> di fianco la lunghezza e la larghezza del parallelepipedo e attraverso la connessione del componente <range>, posso creare dei vettori per tutti i punti di divisione. Posso quindi spostare (<move>) i piani XZ e YZ con questi vettori e generare serie di armature lungo la lunghezza del parallelepipedo limite. 153 Fig. 8.22 Armature generate lungo la direzione della lunghezza e della larghezza del parallelepipedo limite dell'oggetto, perpendicolarmente al bordo. Fig. 8.23 Ora se trovo le intersezioni di questi piani con la superficie, posso effettivamente generare le nervature arrivando a metà strada del nostro processo di fabbricazione delle superfici. Qui ho usato il componente <Brep | Plane> (Intersect>Mathematical>Brep | Plane) per risolvere il problema. Ho usato <Geometry> (la mia superficie iniziale) come Brep e i piani dei passi precedenti, come piani per alimentare i componenti della sezione. 154 Fig. 8.24 Intersezioni tra le armature e le superfici, che creano una di serie di curve sulla superficie. Annidamento Il passo successivo è quello di annidare queste curve di sezione su un foglio piatto per prepararle al processo di taglio. Ho disegnato un rettangolo in Rhinoceroscon il mio foglio. Ho copiato questo rettangolo per generare tanti fogli sovrapposti l'uno con l'altro e ho disegnato una superficie che copra tutti questi rettangoli. Fig. 8.25 Fogli di carta e superfici sottostanti per rappresentarle su Grasshopper Userò il componente <orient> (Xform>Euclidian>Orient) per annidare le mie curve in una superficie che rappresenti i fogli per i tagli. Osservando il componente <orient> potete vedere che abbiamo bisogno del piano di riferimento dell'oggetto e il piano destinazione che dovrebbe essere sul foglio. Quindi dovrei generare questi piani per annidare i miei oggetti di taglio. Poiché ho usato questi piani per intersecare la superficie iniziale e generare le curve di sezione, possono usarli ancora come piani di riferimento, ho quindi solo bisogno di generare i piani di destinazione. 155 Fig. 8.26 Ho importato la superficie di taglio su Grasshopper e ho usato un componente <surface frame> (Surface>Util>Surface frames) per generare serie di strutture trasversali alla superficie. Possiamo generare piani, quanti ne necessita la geometria. Fig. 8.27 Orientamento. Ho connesso le curve di sezione come geometrie di base e i piani che ho usato per genere queste sezione come geometria di riferimento per il componente <orient>. Ma è ancora necessaria una piccola modifica al piano di destinazione. Se osservate i risultati del <surface frame>, vedrete che dividendo la direzione U per 1, verranno generate 2 colonne per dividere la superficie. Ho quindi un numero di piani superiore alle mie necessità. Ed è per questo che ho diviso la lista (<split>) del piano di destinazione con i numeri che provengono dal numero di curve di riferimento. Ho quindi usato piani in quantità pari alle curve presenti e li ho spostati di una unità in direzione X per permettere la sovrapposizione con i bordi dei fogli. Ora possono connettere questi piani al componente <orient>. A questo punto possiamo vedere che tutte le curve sono annidate nel piano di taglio. 156 Fig. 8.28 curve annidate nel foglio di taglio Generazione delle nervature Fig. 8.29 Dopo aver annidato le curve nei fogli di taglio, visto che i nostri oggetti non hanno spessore, abbiamo bisogno di provvedere a tal requisito per poterli tagliare. A questo scopo ho creato un <offset> delle curve con il valore dell'altezza desiderata e ho anche aggiunto delle linee ad entrambe le estremità di queste curve e di quelle 'offsettate' in modo da chiudere l'intero disegno ed avere la nervatura completa per il taglio. Generare le giunture (imbrigliatura) Il passo successivo è quello di generare le nervature nelle altre direzione e creare le giunture per assemblare dopo il taglio. Sebbene abbia usato lo stesso metodo di divisione dell'altezza del 157 parallelepipedo limite per generare piani e quindi sezioni, posso generarli manualmente in ogni posizione desiderata. Quindi, se non volete dividere entrambe le direzioni e generare le sezioni, potete usare altri metodi. Fig. 8.30 Come vedete in questo caso, al posto dei piani precedentemente generati, ho usato piani definiti manualmente per le sezione nelle altre direzioni delle superfici. Un piano è statp generato attraverso un valore di X direttamente da un <number slider> ed un altro piano proveniene da un piano specchiato sull'altro lato della superficie (lunghezza della superficie (y) – number slider (x)). Le sezione di questi due piani e superfici sono calcolate per i passi successivi. Ora posso orientare queste nuove curve su un altro foglio da tagliare, usando lo stesso processo precedente. Generiamo quindi le giunture per l'assemblaggio della parti. Fig. 8.31 Poiché abbiamo le curve nelle due direzioni, possiamo trovare i loro punti di intersezione per disegnare le giunture nella posizione corretta. A questo scopo ho usato il componente <CCX> (Intersect>Physical>Curve|Curve) per trovare le posizioni di intersezione tra queste curve cioè le posizioni delle giunture (Il componente <CCX> è impostato in modalità riferimento incrociato (cross reference)). 158 Ho bisogno di disegnare disegnare qualcos'altro per preparare la giunture al taglio. Ho intenzione di usare un'imbrigliatura e ho quindi bisogno di tagliare metà di ogni nervatura nella posizione di giuntura per poter unirle alla fine. Per prima cosa ho bisogno di trovare queste intersezioni nelle nervature nidificate e quindi disegnare la linea di taglio. Fig. 8.32 Se osservate la porta di output del componente <CCX> potrete vedere che restituisce il parametro in cui ogni curva si interseca con l'altra. Posso quindi valutare le curve nidificate o orientate con questi parametri per trovare la posizione di giuntura sui fogli di taglio. Fig. 8.33 Ora che abbiamo la posizione delle giunture, dobbiamo disegnarle. Per prima cosa ho disegnato le linee con il componente <line SDL> con il punto di giunzione quale punto di partenza, direzione <unit Y> e ho usato mezza altezza della nervatura come valore per la lunghezza. Ora possiamo vedere che punto sulla curva nidificata ha una linea sottile associata. 159 Fig. 8.34 Passo successivo, disegnate una linea in direzione X dal punto finale della precedente linea con la lunghezza del <sheet_thikness> (spessore del foglio, che dipende dal materiale). Fig. 8.35 Per disegnare la terza linea ho bisogno di trovare il punto dove questa linea si connette alla curva di base perchè non conosco esattamente la lunghezza. In questo passaggio, ho aggiunto un altra <linea SDL> con direzione Y ma segno negativo per disegnare la terza linea, ma più lunga di quanto necessario, per intersecare la curva di base in un punto. Il <receiver> è connesso alla curva orientata. Ho quindi usato <CLX> (Intersect>Mathematical>Curve|line) per trovare l'intersezione con la curva di base. Ho 'appiattito' (<flatten>) e aggiunto delle linee, ancora dal punto finale della seconda linea a questo punto di intersezione. Come risultato, ora le connessioni sono complete. Devo completare il lavoro per entrambi i lati di giunzione. 160 Fig.8.36 Usando un componente <join curves> (Curve>Util>Join curves), come potete vedere ho una scanalatura (chiamata <join curve>) che possono usare per tagliare, come imbrigliatura dentro la struttura. Applichiamo lo stesso metodo per l'altra estremità della curva (seconda serie di giunzioni sull'altro lato della curva orientata). Fig. 8.37 Nervature con il punto di giunzione disegnato su entrambe le estremità. Posso tagliare la parte sottile della curva di base dentro la giuntura, ma, visto che non modifica la geometria, la posso lasciare. Etichettatura Mentre stiamo lavorando nella fase di fabbricazione, potrebbe non essere una grande idea, tagliare centinaia di piccole parti e lasciarle senza nome e indicazioni. Visto che stiamo andando ad 161 assemblarle, sarebbe opportuno indicarne l'ordine per sapere quale va per prima. E' ovvio che visto che tutte le parti sono diverse, abbiamo bisogno di etichettarle per poterle assemblare facilmente. L'etichetta può essere semplicemente rappresentata da un numero o da una combinazione di numeri e testi utili a collocare i pezzi. Se l'oggetto è composto da una serie di piccoli pezzi divis, possiamo dare un nome alle parti principali e usare il nome o le iniziali con i numeri per collocare i pezzi (p.e. left_wing_01 – ala_sinistra_01). Possiamo usare anche delle logiche gerarchiche per poter nominare anche le parti (p.e. layer_01_p_45). Ho dunque bisogno di una serie di numeri per mostrare la posizione delle nervature nella lista. Posso usare il componente <text tag> per poter aggiungere il testo alla mia geometria e per fare ciò, ho bisogno di indicare la posizione e l'altezza del testo. Fig. 8.38 Come ricorderete, ho una serie di piani che usati come piani di destinazione per orientare le curve di sezione sul foglio. Andrò quindi ad usare i piani per creare le posizione per il testo. Poiché i piani sono esattamente agli angoli dellenervature, li devo prima spostare. Fig. 8.39 Ho spostato gli angoli dei piani di una unità in direzione X e di mezza unità in direzione Y (come somma (<sum>) di vettori) ed ho usato questi piani per la posizione delle etichette testuali. Qui ho usato <text tag 3D> e ho generato una serie di elementi pari al numero delle nervature e li userò come testo. Per convertire 12.0 in 12 ho usato il componente <integer> ma è possibile farlo anche con una funzione. Come risultato potete vedere tutte gli elementi che presentano un unico numero nel loro angolo sinistro. 162 Fig. 8.40 Ora potete cambiare i fattori di divisione delle superfici di taglio per comprimere le nervature, in modo da evitare di sprecare materiale. Come vedete nell'esempio precedente, dal punto di partenza del foglio 3 (sheet_3), le nervature iniziano ad essere più piatte e questo consente di avere più spazio tra loro. Qui potete suddividere le vostre nervature in due diverse superfici da tagliare e cambiare i punti di divisione, per comprimerli in base alla loro forma. Ma se non state tenendo conto di alcune parti potete fare questo tipo di cose manualmente su rhino: non è necessario che tutte le parti siano fatte in maniera associativa! Ora ho le nervature in una direzione e posso fare le stessa cosa nell'altra direzione. L'unico cosa da considerare è la direzione dei giunti invertita, quindi mentre stavo lavorando con la geometria orientata nella parte precedente, qui devo lavorare con quella creata dall'<offset> Taglio Quando tutte le geometrie diventano pronte per essere tagliate, ho bisogno di 'cucinarle' (bake) e modificarle un altro po' sui fogli. Come vedete in fig. 8.41 gli oggetti sono tutti nidificati in tre fogli. Ho generato tre forme diverse per le nervature nella direzione della larghezza dell'oggetto per verificarle. Il materiale è ora pronto per essere tagliato. Fig. 8.41 Nervature annidate, pronte per essere tagliate. 163 Fig. 8.42 Esempi di nervature, pronte per essere assemblate. Assemblaggio Nel nostro caso, l'assemblaggio, è relativamente semplice. Talvolta sarà necessario controllare ancora il file per avere un aiuto nell'assemblare le parti con diversi metodi di fabbricazione. Qui abbiamo tutte le superfici fatte con i fogli di carta. 164 Fig. 8.43 Modello finale La fabbricazione è un argomento di discussione molto vasto. Dipende principalmente su cosa si vuole fabbricare, qual'è il materiale, qual'è la macchina da utilizzare, come le parti fabbricate vanno assemblate e così via. Come già detto, in base al progetto su cui si intende lavorare, avrete bisogno di recuperare i dati per per le fasi di fabbricazione. Qualche risulterà più importante avere la logica di assemblaggio, per esempio quando state lavorando con componenti semplici che creano posi una geometria complessa come risultato dell'assemblaggio. 165 Fig. 8.44 Logica di assemblaggio: i materiali e i giunti sono semplici. Posso lavorare sulla logica di assemblaggio e usare i dati per fare i miei modelli. 166 CAPITOLO_9_ Strategia di Design 167 9_Strategia di Design Gli algoritmi generativi sono algoritmi e rappresentano modalità associativo/parametrico di operare sulla geometria nelle problematiche progettuali. Con il metodo algoritmico, meglio che con che con gli oggetti geometrici convenzionali, possiamo avere tutte le possibilità date dalla geometria computazionale, e allo stesso tempo possiamo gestire un'immensa quantità dai dati, numeri e calcoli. La problematica è quella di non limitare la progettazione in esperimenti predefiniti, ed esplorare le infinite potenzialità; ci sono sempre modi alternativi per impostare gli algoritmi di design. Sebbene sembri che i comandi degli applicativi sulla modellazione parametrica possano limitare alcune operazioni o possano imporre dei metodi, le soluzioni alternative sono sempre presenti: fate volare la fantasia e scavalcate i limiti! Per poter progettare qualcosa,aiuta sempre avere una strategia progettuale. Questa permetterà di impostare il miglior algoritmo per trovare la soluzione al nostro problema. Pensando alle proprietà generali degli oggetti di design, disegnare alcune parti e fare dei modelli fisici, potrebbe aiutare a capire meglio gli algoritmi in modo da scegliere i migliori componenti per la modellazione digitale. Pensando ai parametri fissi, questi possono essere cambiati durante il progetto: i dati numerici e gli oggetti geometrici necessari, aiutano sempre a migliorare l'algoritmo. Sarebbe veramente d'aiuto capire analiticamente le problematiche progettuali, schizzarle e quindi iniziare un algoritmo che possa risolvere il problema. Per poter progettare algoritmicamente, dobbiamo pensare algoritmicamente! 168 Fig. 9.1 Progetto Weaving, dalla comprensione analitica alla modellazione associativa. 169 Fig. 9.2 Progetto di un muro forato, Dalla comprensione analitica alla modellazione associativa. 170 Bibliografia Pottman, Helmut and Asperl, Andreas and Hofer, Michael and Kilian, Axel, 2007: ‘Architectural Geometry’, Bently Institute Press. Hensel, Michael and Menges, Achim, 2008: ‘Morpho-Ecologies’, Architectural Association. Rutten, David, 2007: ‘RhinocerosScript 101’, digital version by David Rutten and Robert McNeel and Association. Flake, Gary William, 1998: ‘The computational beauty of nature, computer explorations of fractals, chaos, complex systems, and adaptation’, The MIT Press. De Berg, Mark and Van Kreveld, Marc and Overmars, Mark, 2000: ‘Computational Geometry’, Springer. Grasshopper tutorials on Robert McNeel and Associates http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryExamples.html wiki: Axel Kilian and Stylianos Dritsas: ‘Design Tooling - Sketching by Computation’, http://www.designexplorer.net/designtooling/inetpub/wwwroot/components/sketching/index.ht ml Wolfram Mathworld: http://mathworld.wolfram.com/ Stylianos Dritsas, http://jeneratiff.com/ Main Grasshopper web page: http://Grasshopper3d.com 171 172