projektowanie parametryczne, parametric design
Home > Grasshopper, O co chodzi > Grasshopper – Poradnik cz. 1 – Atraktory /średnio zaawansowany/

Grasshopper – Poradnik cz. 1 – Atraktory /średnio zaawansowany/

Grasshopper – Poradnik cz. 1 – Atraktory

/średnio zaawansowany/



Grasshopper ? Podstawy cz. 1
Grasshopper ? Podstawy cz. 2
Grasshopper ? Podstawy cz. 3

Temat poradnika

Jeżeli dopiero zaczynasz swoją przygodę z Grasshopper’em – przeczytaj najpierw trzy części podstaw. Linki znajdziesz u góry.
Ćwiczenie opracowane dla Grasshopper built 0.8010. Niemniej jednak wszystko co tu opiszę da się wykonać identycznie nawet w dużo starszych wersjach programu.

     Pierwszą część poradnika dla średnio zaawansowanych poświęcam atraktorom. Znajomość podstaw jest wymagana, stosuję w tym ćwiczeniu wiele skrótów myślowych.

Dlaczego atraktory ?

     Pomijając swoją skomplikowaną definicję encyklopedyczną, atraktory są bardzo łatwym zagadnieniem dla “adeptów” Grasshopper’a. Rządzą się bardzo prostym prawem – “im bliżej tym… im dalej tym… “. W ćwiczeniu nie będzie nawet “zabawy” z listami danych – w tej kwestii użyjemy bardzo prostych komponentów. Mimo to na forum Grasshopper’a pojawiają się jednak co jakiś czas pytania o atraktory, w szczególności o to jak użyć większej ilości punktów “atrakcyjnych” ;) . W naszym ćwiczeniu będziemy mogli zastosować dowolną ilość atraktorów.

Atraktory w naturze

     Jeśli przeczytaliście artykuł na wikipedii o atraktorach, możecie mieć do nich mieszane uczucia. Gdybym jednak czytał definicje matematyczne wszystkiego co można znaleźć w Grasshopperze, to nigdy bym go nawet nie uruchomił na swoim komputerze. Dlatego podam parę linków ze strony Zahy Hadid ukazujących możliwości atraktorów :

Elewacja
Wzór przetłoczony na ścianie
Okna dachowe

     W przyrodzie atraktorem może być np. wysokość nad poziomem morza – rośliny potrzebują odpowiednich warunków, które są dostępne tylko na danej wysokości (nasłonecznienie, ilość tlenu, podłoże itp.). W ten sposób możemy zaobserwować gradient częstości występowania danego gatunku względem wysokości.

Ćwiczenie



Efekt jaki chcemy uzyskać

     Zastanówmy się więc – na czym polega logika tej geometrii? Zanim zaczniemy układać algorytm, musimy jasno sprecyzować czego od niego oczekujemy. Mój atraktor działa na siatkę trójkątną (Triangular grid), obracając i przeskalowując trójkąty siatki w stopniu zależnym od odległości do punktu atraktora. Atraktorów może być wiele (to oznacza, że nie może być maksymalnej liczby możliwych atraktorów).

Po takim naszkicowaniu logiki naszego algorytmu, przystępujemy do działania.

Plan działania…

…wygląda następująco :

  1. Tworzymy siatkę trójkątną
  2. Określamy punkty atraktora
  3. “Filtrujemy” odległości, tak aby przejścia pomiędzy atraktorami były płynne
  4. Konwertujemy dane tak aby mieć pełną kontrolę nad kątami obrotu i stopniem powiększenia zadanych trójkątów.
  5. Nadajemy maksymalny kąt o jaki mogą się obrócić trójkąty
  6. “Odwracamy” wartości kątów, celem wykorzystania ich do skalowania
  7. Po skalowaniu offsetujemy trójkąty, tak aby na siebie nie zachodziły

Tworzymy siatkę trójkątną; określamy punkty atraktora





     W kategorii “Vector” znajdziemy siatkę trójkątną. Zadajemy na wejścia Ex i Ey po jednym sliderze (właściwości : Integer, 1-30). Wielkość oczek (wejście “S”) jest nieistotna, możemy ją zmienić jednak dla własnej wygody.
     Tak jak wspominałem w podstawach, należy (także z powodu wygody) unikać tworzenia obiektów referencyjnych. Dlatego wstawiamy komponent “Point” (kategoria “Params”), klikamy na niego prawym klawiszem, a następnie wybieramy dwa-trzy dowolne punkty znajdujące się w okolicach siatki (robimy to w oknie Rhino, wcześniej wybierając typ punktu “Coordinates” -> patrz linia komend). To będą nasze atraktory.

“Filtrujemy” odległości, tak aby przejścia pomiędzy atraktorami były płynne





     Aby prawidłowo “przefiltrować” dane odległości, musimy wybrać te najkrótsze, tj. mając trzy atraktory, każda komórka siatki ma możliwość przejęcia tylko jednej z trzech odległości – w naszym przypadku najkrótszej. Dlatego musimy porównać odległości w trójkach – najpierw komórki siatki przechodzą przez “flatten” (usuwamy wszelkie dane na temat adresu komórki), później stosujemy “graft” tak aby każda komórka miała swoją “gałąź” w “drzewie danych”. Teraz umieszczamy komponent “Distance” na płótnie – do wejścia “A” podłączamy nasze komórki, do “B” natomiast punkty atraktora. Gdybyśmy nie zastosowali “graft” na komórach siatki, komponent “Distance” porównałby dane zgadzające się indeksami (indeksy 1, 2, 3), następne indeksy siatki byłyby porównywane z ostatnim atraktorem.
(Patrz tutorial “Podstawy cz.1″; “longest list”)

Konwertujemy dane tak aby mieć pełną kontrolę nad kątami obrotu i stopniem powiększenia zadanych trójkątów.





     Odległości jakie otrzymaliśmy po ich porównywaniu, mogą przyjmować najróżniejsze wartości. Często można się spotkać z tym, że ktoś do dalszej pracy zmienia je poprzez mnożenie, dodawanie, odejmowanie itp. To jednak nie daje nigdy pełnej kontroli nad wartościami, dlatego powinniśmy je przekonwertować na wartości mieszczące się w zadanym przedziale (można sobie wyobrazić “przeskalowanie” wartości do odpowiadającego “wymiaru”). Użyjemy zatem komponentu “Remap values”. Posiada on trzy wejścia : wartości “V”, źródłowy przedział liczbowy “S” oraz przedział liczbowy docelowy “T”. Do V podłączamy nasze “przefiltrowane” wartości. Użyjemy na nich także komponentu “Bounds”, aby stworzyć z nich przedział liczbowy “Domain” – podłączamy go do wejścia “S”. Ostatnim krokiem jest zadanie przedziału w którym mają się mieścić nowe wartości, standardowo jest to od 0 do 1 – i tyle zostawiamy. (“Flatten” na wejściu “V” został użyty celem dalszej “obróbki”)

Nadajemy maksymalny kąt o jaki mogą się obrócić trójkąty





     Dzięki temu, że przekonwertowaliśmy zbiór wartości na zbiór mieszczący się w przedziale od 0 do 1, mamy teraz pełną kontrolę nad kątem obrotu trójkątów. Domyślnie kąt obrotu w Grasshopperze podawany jest w radianach – dlatego żeby określić maksymalny kąt obrotu użyjemy liczby pi (kategoria “Math”). Jako że operujemy na trójkątach, maksymalny kąt obrotu ustalamy na pi/3 (60 stopni). Mnożymy pi/3 razy nasze wartości. Umieszczamy komponent “Rotate” na płótnie, do wejścia “G” podczepiamy wyjście “C” z “Triangular grid”; do wejścia “A” nasze wartości po pomnożeniu przez pi/3; do wejścia “P” zadajemy punkty z wyjścia “P” komponentu “Triangular grid” (środki trójkątów). Wszystkie wejścia muszą wcześniej zostać ustawione na “flatten”, inaczej adresy obiektów i wartości nie będą sobie odpowiadać. Po podłączeniu wszystkiego, możemy spojrzeć na okno Rhinocerosa – widzimy już obrócone trójkąty.

“Odwracamy” wartości kątów, celem wykorzystania ich do skalowania





     Nasze “trójkąty” po obróceniu (na wyjściu “G” komponentu “Rotate”) poddajemy następnie przeskalowaniu. Możemy to zrobić poprzez wyciągnięcie cosinusa ze “zmapowanych” wartości (wyjście “R” komponentu “Remap values”). Dzięki zastosowaniu cosinusa nasze trójkąty maleją wraz ze wzrostem odległości od atraktora. Daje to całkiem ciekawy efekt. Jeśli byśmy nie zastosowali cosinusa, trójkąty powiększałyby się wraz ze wzrostem odległości do atraktora (patrz -> wykres funkcji cosinus).

     Jednak kiedy przyjrzeć się bliżej, widać wyraźnie że trójkąty nakładają się na siebie.




Po skalowaniu offsetujemy trójkąty, tak aby na siebie nie zachodziły





     Zachodzenie na siebie krzywych, może być problemem np. przy wycinaniu ploterem laserowym. W efekcie dostalibyśmy setki luźnych elementów. Dlatego należy zachować odstępy pomiędzy trójkątami. Tradycyjnie można to zrobić za pomocą offsetowania (komponent “Offset”), jednak w tym przypadku zastosuję komponent “Scale”. Działa on dużo szybciej niż offsetowanie, dzięki czemu możemy płynnie zmieniać naszą zmodyfikowaną siatkę. Efekt jest oczywiście odrobinę inny niż offset, lecz dla naszej geometrii nie ma to zbyt wielkiego znaczenia.
     Do analizowania czasu potrzebnego na obliczenia użyteczny jest “Profiler”. Można go znaleźć w Pasek menu -> View -> Wigdets -> Profiler. Jest on bardzo przydatny przy optymalizowaniu algorytmu. Podaje czas potrzebny na przeliczenie każdego komponentu na płótnie. Dzięki temu można zobaczyć ,który komponent stanowi “wąskie gardło” i zmodyfikować algorytm tak, aby działał szybciej.




Algorytm w GH i efekt w Rhino



Efekt końcowy



Obrazek, na którym można zobaczyć cały przebieg tego tutoriala.

Na zakończenie


     To już koniec poradnika na temat atraktorów. Jeśli ktoś uzna, że naprawdę rozumie “jak to te atraktory działają” można się pokusić o spróbowanie utworzenia atraktora w postaci krzywej, lub nawet bryły (jest to naprawdę proste).
     Następna część poradnika będzie o strukturach waflowanych (bardzo kiepskie tłumaczenie ;) ). Jak zwykle czekam na komentarze i przede wszystkim pytania.

  1. kacper
    wrzesień 5th, 2011 at 19:51 | #1

    Witam,

    beda kolejne tutoriale?

    Dobra robota!

  2. Mat O.
    październik 6th, 2011 at 00:35 | #2

    Nice. Czekam na następny tutorial – ten bardzo wiele tłumaczy i jest napisany całkiem przejrzyście bez zbędnego gadania! Btw – mógłbyś napisać coś więcej o “BOX MORPH” z tutoriala nr3 ??
    Z góry dzięki

  3. Ubicz
    listopad 22nd, 2011 at 02:34 | #3

    Swietnie, fajnie ze ktos po polsku opisuje ten program! Angielski niby znam nieźle, ale mimo wszysto po polsku idzie szybciej i lepiej zapamietuje dane.

    Kiedy będzie następny tutorial?

  4. grudzień 24th, 2011 at 06:18 | #4

    @kacper, Ubicz – następny tutorial będzie o “waflowaniu” (czy też “grillowaniu”). Mam już mniej więcej ogarnięty plik w GH, ale tym razem zmienię formę tutoriala na wideo + tekst. Swoją drogą jak dobrze pójdzie to będzie do jeden z najbardziej efektywnych czasowo sposobów na “grillowanie” (bez operacji booleanowskich)

  5. grudzień 24th, 2011 at 06:19 | #5

    @Mat O. – box morph opiszę kiedyś przy tutorialu na temat różnych sposobów panelizacji. Trochę jednak to potrwa zanim ten tutorial się tutaj znajdzie.

  6. kuba k.
    marzec 9th, 2012 at 17:00 | #6

    Świetna robota z tymi tutorialami. Od tygodnia siedzę na nich i staram się jak najwięcej z nich wyciągnąć. Kiedy będą kolejne?

  7. kuba k.
    marzec 9th, 2012 at 17:49 | #7

    Mateusz. Pomiędzy Distance a Remap Values jest jeszcze “Sort” oraz “Item”. Do czego one służą tutaj?

  8. marzec 10th, 2012 at 01:38 | #8

    @kuba k. – dla każdego punktu z siatki wyznaczamy 3 odległości (do trzech atraktorów), sortujemy (Sort) wyniki aby znaleźć najbliższy z 3 atraktorów. List item (z parametrem “0″ w wejściu “i”) wybiera nam tą najbliższą odległość (ktora potem służy do skalowania i obracania)

  9. kuba k.
    marzec 10th, 2012 at 19:46 | #9

    Mateusz Z- jeszcze jednego nie rozumiem. Jak to się dzieje, że siatka trójkątów w którymś momencie uwolniła komórki i każdy z nich jest jakby osobnym elementem? Może to dziwne pytanie, ale jakoś nie mieści mi się to w głowie, że te trójkąty ze sztywnej i powtarzalnej siatki stały się nagle osobnymi elementami każdy- chyba, że cos pominąłem. Któryś z elementów skryptu “obrysowuje” lub jakby rozbija je?

  10. zet
    czerwiec 29th, 2012 at 16:52 | #10

    kuba, ten element siatka ma po prostu takie wyjscie – “trojkaty”. Wszystko co do niego podlaczysz dotyczy wlasnie trojkatow, ktore sa samodzielnymi figurami, nie calej siatki!