Archive

Posts Tagged ‘Processing’

Generative cities – Processing in urban planning

April 28th, 2012 2 comments

Can algorithms help with designing cities ? This question has been researched by scientists and designers for a while already, but there is no clear answer so far. There are many works published, there are also software packages available (like CityEngine) that can create whole cities for visualisation or animation purposes.

We’ve been trying to find some answers for these questions during generative design and modelling course run at Faculty of Architecture at TU Wrocław. Using simulated artificial life processes (agent based systems)  programmed in Processing language, and special bitmaps with street topologies, we were trying to generate complex urban tissue. The base of the algorithm was to exchange data about location, proximity and number of neighbouring objects/buildings on local level, negotiating their own position with surroundings.

Emergent algorithms utilized in this tasks were dynamic relaxation, density sensing, and automatic orientation procedures that move/rotate object depending on street map and local negotiations. Main rule was to make each building ‘fight’ for best place in currently unbuilt areas, and then to rotate the building so it uses best views.

All these ideas were fully programmed in few pages of Processing code. It must be noted that these were not proper research experiments, but rather ‘code sketching’ exercises, aimed at understanding the dynamics of generative and adaptive processes, such as aggregation and self organization in large scale.

What was the outcome ? See for yourself !

(Daniel Karcher)

(Stanisław Puda)

(Mateusz Kozica)

(Anna Sinkowska)

(Piotr Suskiewicz)

Przykładowa bitmapa wykorzystana do wygenerowania sztucznego miasta wyglądała tak :

Zdarzały się także miasta kosmiczne :-)

(Katarzyna Zielińska)

All models were generated in Processing environment, and then exported as 3D DXF files, to finally be visualised in external rendering programs (Generative Components, Autodesk Revit, 3d Max itp).

Processing – krzywe Beziera

November 14th, 2009 4 comments

dach01

W kolejnej lekcji języka programowania Processing (poprzednia jest tutaj), zajmiemy się krzywymi Beziera. Dlaczego ? Ponieważ krzywe te są bardzo często podstawowym środkiem definiowania nie-liniowej geometrii np. fasad lub dachów. Nie są one co prawda tak popularne jak krzywe B-Spline (chociaż są ich najprostszą wersją), lub ich rozszerzona wersja – NURBS, ale od nich wszystko się zaczęło, więc warto przyjrzeć się im z bliska (są na przykład używane w programie Adobe Illustrator).

Na początek omówimy podstawy tworzenia krzywych, i kilka technicznych elementów pomocnych w kreowaniu trójwymiarowych struktur w Processing. Potem stworzymy program rysujący powierzchnię dachu (jak powyżej) i eksportujący ją do pliku.

————————————————————–

Spróbujmy napisać kilka lini kodu rysujących przykładową krzywą Beziera. Aby to zrobić potrzebujemy czterech punktów – początku, czyli tzw. pierwszego punktu zakotwiczenia, dwóch punktów kontrolnych, i drugiego punktu zakotwiczenia, czyli końca krzywej.

Zdefiniujmy zatem łańcuch współrzędnych: cztery współrzędne X (łańcuch będzie miał nazwę ‘px’), i cztery współrzędne Y (łańcuch o nazwie ‘py’)

float px [] = new float[4];
float py [] = new float[4];

w ten sposób zdeklarowaliśmy oba łańcuchy, które są teraz gotowe do użycia. Każdy z nich ma cztery pozycje, w których będzie trzymał jedną współrzędną. Przypiszmy im zatem teraz wartości – współrzędne punktów kontrolnych i skrajnych dla krzywej, w układzie współrzędnych XY (liczonym od lewego górnego rogu okna).

px[0] = 50; py[0] = 50;  //pierwszy punkt kontrolny – początek krzywej
px[1] = 40; py[1] = 170; //drugi punkt kontrolny
px[2] = 270; py[2] = 170; //trzeci
px[3] = 250; py[3] = 250; //czwarty – koniec krzywej

size(300,300); //otwórzmy okno o rozmiarach 300 x 300 pikseli

noFill(); //wyłączmy wypełnianie obiektów (o tym później)

bezier(px[0],py[0],  px[1],py[1],  px[2],py[2],  px[3],py[3]); //i narysujmy krzywą

Po wpisaniu powyższego kodu do edytora i naciśnięciu przycisku start, powinniśmy zobaczyć poniższy obraz :

bezier_1Wygląda ciekawie, ale nadal trochę tajemniczo..  Żeby zrozumieć lepiej, jak działają krzywe beziera, narysujmy punkty kontrolne. Dodajmy na końcu poniższe linie :

fill(255,0,0); //zmieniamy kolor na czerwony (podając kolejno wartości r, g, b)
ellipse(px[0], py[0] ,8,8); //punkt nr 1
ellipse(px[1], py[1] ,8,8); //punkt nr 2
ellipse(px[2], py[2] ,8,8); //punkt nr 3
ellipse(px[3], py[3] ,8,8); //punkt nr 4

a żeby zobaczyć jak wygląda tak zwany ‘control polygon’, połączmy je liniami:

stroke(50,100); //ustawiamy kolor i przezroczystość linii
line(px[0], py[0] ,px[1], py[1]);
line(px[1], py[1] ,px[2], py[2]);
line(px[2], py[2] ,px[3], py[3]);

Po dodaniu powyższych linii, uruchamiamy szkic (przyciskiem run, albo ctrl+R) i widzimy krzywą jak poniżej :

bezier_2

Patrząc na ten przykład, można łatwo zauważyć podstawową właściwość krzywej Beziera : początek i koniec są styczne do linii kontrolnych, a to można sprytnie wykorzystać przy tworzeniu bardziej skomplikowanych geometrii.

Spróbujmy teraz zrobić z tego coś ciekawszego, czyli wykorzystać replikację (poprzez użycie pętli FOR – więcej informacji o tym jak jej używać jest w poprzednim tutorialu). Generalnie najciekawsze efekty daje niewielka modyfikacja współrzędnych punktów kontrolnych, i narysowanie wszystkich tak powstałych krzywych razem obok siebie. Dodajmy zatem :

noFill(); //wyłączamy wypełnianie
for (int i=0;i<20;i++) //uruchamiamy pętlę na 20 powtórzeń
{
px[0] = px[0]+5; //przesuwamy punkt 0 w prawo
py[1] = py[1]+8; // punkt 1 w dół
py[2] = py[2]-4; //punkt 2 w górę
px[3] = px[3]+2; //punkt 3 lekko w prawo
bezier(px[0],py[0],  px[1],py[1],  px[2],py[2],  px[3],py[3]); //i rysujemy krzywą
}

bezier_3

Ciekawą wizualizację krzywych razem z liniami kontrolnymi można uzyskać przenosząc dwie linijki kodu:

for (int i=0;i<20;i++)
{

nad linię z komendą fill(255,0,0); , ponieważ wtedy w pętli znajdzie się procedura rysowania linii i czerwonych kółek. Otrzymamy wtedy obraz pokazujący dokładnie ‘wędrówkę’ punktów kontrolnych :

bezier_4

Przy zabawie parametrami można pójść trochę dalej, i dodając do nich kilka sinusów,  otrzymać geometrię jak poniżej :

bezier_6

Pewnie ktoś z czytelników zapyta.. ‘ok, wporządku, ale do czego można tego teraz użyć’ ? Otóż w parametrycznym modelowaniu często spotykamy się z modelowaniem jakiejś powierzchni (np dachu) przez przeciągnięcie jednego profilu wzdłuż krzywej (tzw. szyny – ‘sweep profile along rail curve’ ), lub zbudowanie z wszystkich krzywych jednej powierzchni (‘loft curves’). Tak też spróbujemy zrobić za kilka chwil.

——————————————————————————-

Najpierw jednak, aby ułatwić nam nieco modelowanie trójwymiarowych obiektów, i ich przestrzenną ocenę, musimy dodać do programu element interaktywny. Inaczej będziemy ciągle w dwuwymiarowym, statycznym świecie. Ta mała dygresja jest raczej konieczna do tego, żeby przejść do kolejnego, bardziej ekscytującego (!) etapu programowania w trzech wymiarach.

W Processing możemy pisać programy na dwa sposoby : liniowy, gdzie zwyczajnie wpisujemy komendy jedna po drugiej, np :

size(300,300,P3D); //ustawiamy okno

translate(150,150); //przesuwamy układ współrzędnych na środek ekranu (połowa szerokości, połowa wysokości)

rotateX(PI/3); //obracamy układ współrzędnych wokół osi X
rotateZ(PI*1.7); //i wokół osi Y

box(50); //i rysujemy sześcian

W ten sposób program wykonuje wszystkie polecenia po kolei, i zatrzymuje się na końcu. Możemy w międzyczasie wykonywać pętle, definiować wiele graficznych elementów i pisać nieskończone ilości instrukcji – ale wszystko zostanie wykonane tylko raz.

Drugi sposób, to sposób nieliniowy, interaktywny i zorientowany zdarzeniowo. To znaczy, że po uruchomieniu programu, instrukcje będą wykonywane w niekończącej się pętli (ok 20-30 razy na sekundę), a program może w tym czasie rysować dowolne rzeczy, wydawać dźwięki, odgrywać video, i co najważniejsze reagować na zdarzenia. Takimi zdarzeniami zazwyczaj są manipulacje myszką i naciskanie klawiszy na klawiaturze, ale może to też być bardziej skomplikowany bodziec, jak na przykład obraz z kamery video, lub dźwięk z mikrofonu.

Program taki wygląda tak:

void setup()
{
println(“ta instrukcja wykona się 1 raz”);
}

void draw()
{
println(“ta instrukcja wykona się wiele razy”);
}

Czyli ma dwie części : setup, i draw. Pierwsza wykonuje się tylko raz, dokonujemy w niej ustawienia okna, początkowych zmiennych, ładujemy czcionki, obrazy i dźwięki. Druga (draw) to część która będzie wykonywać się w nieskończoność, dopóki nie zakończymy programu.

Ten sam program, w wersji interaktywnej będzie wyglądał tak :
void setup()
{
size(300,300,P3D);
//ustawiamy okno (włączamy też tryb pracy w trzech wymiarach)
}

void draw()
{
background(160);
//czyścimy tło przed narysowaniem czegokolwiek

translate(150,150); //przesuwamy układ współrzędnych na środek ekranu (połowa szerokości, połowa wysokości)

rotateX(mouseY*PI/300); //obracamy układ współrzędnych wokół osi X (wykorzystujemy pozycję myszki!)
rotateZ(mouseX*PI/300); //i wokół osi Y

box(50); //i rysujemy kostkę
}

Po uruchomieniu powyższego kodu, zobaczymy radośnie obracający się sześcian :)

box01

——————————————————————————-

Po tej małej dygresji zacznijmy więc nowy szkic (wybierając z menu File >> New). Na początek, tak jak poprzednio, deklarujemy współrzędnych punktów kontrolnych

float px [] = new float[4];
float py [] = new float[4];

I przejdźmy do trybu 3D – robi się to poprzez deklarację size(szerokość, wysokość, tryb).  Tryb może być wyrażony przez P3D – standardowy silnik Javy (działa w oknie przeglądarki stron www), albo przez OPENGL – szybszy i dużo lepszy graficznie silnik, ale działający tylko w oknie Processingu albo po skompilowaniu szkicu do pliku .exe.

void setup()
{
size(600,400,P3D);
//tworzymy okno (tym razem trochę większe!)
}

i zaczynamy część ‘dynamiczną’

void draw()
{

background(160); //czyścimy tło
translate(300,200);//przesuwamy układ współrzędnych na środek

rotateX(mouseY*PI/300); //i obracamy go wokół osi X
rotateZ(mouseX*PI/300); //i osi Z

noFill(); //bez wypełniania
stroke(250,160); //rysujemy białym, lekko przezroczystym kolorem

Współrzędne punktów będą teraz trochę inne, a nasza krzywa będzie przypominać odwróconą literę ‘U’. Narysujemy ją 120 razy, przesuwając ją stopniowo  (użyjemy znowu pętli FOR). Zauważ, że zamieniliśmy współrzędną Y ze współrzędną Z (gdzie współrzędna Y przesuwa się od -60 do 60).

for (int i=-60;i<60;i++)
{
px[0] = -100; py[0] = -50;
px[1] = -80;     py[1] = 150;
px[2] = 80;      py[2] = 150;
px[3] = 100;    py[3] = -50;

bezier(px[0],  i*2,  py[0],   //współrzędne pierwszego punktu (początku krzywej)
px[1 ],  i*2,  py[1],    //współrzędne drugiego punktu
px[2],  i*2,  py[2],   // trzeciego
px[3],  i*2,  py[3]);
//i czwartego (koniec)
}

}

Po uruchomieniu programu, widzimy naszą pierwszą prawdziwie trójwymiarową powierzchnię :

bezier_07

W tym momencie nasz ‘dach’ jest poprostu zwyczajną powierzchnią ‘translacyjną’, czyli powstałą poprzez translację (przesunięcie) profilu w przestrzeni. Prawdziwa zabawa zacznie się jednak dopiero, gdy zaczniemy modulować profil podczas przesuwania. Jak to zrobić ? Wystarczy przy każdym przebiegu pętli zmienić lekko współrzędne punktów kontrolnych. Dobrze jest użyć do tego funkcji Sinus lub Cosinus, ponieważ łatwo nią sterować za pomocą amplitudy i okresu. Na przykład jeśli w naszej pętli zmienna i przechodzi od wartości -60 do 60, to dodając do którejś współrzędnej wyrażenie sin(i/60 * PI) * 50 , wartość wyrażenia przejdzie płynnie od sin(-PI)*50 do sin(PI)*50, czyli od -50 do 50, oczywiście płynnym ruchem, jak na sinusoidzie.

Dodając kilka takich kombinacji można uzyskać poniższy efekt :

bezier_08

A kod generujący krzywiznę wygląda tak :

for (int i=-60;i<60;i++)
{
px[0] = -100;                   py[0] = -50+sin(i*PI/60.0)*25;
px[1] =  -80+sin(i*PI/45.0)*50; py[1] = 50;
px[2] =   80;                   py[2] = 50;
px[3] =  100+sin(i*PI/60.0)*25; py[3] = -50+sin(i*PI/40.0)*15;
bezier(px[0],  i*2,  py[0],
px[1],  i*2+sin(i*PI/120.0)*150,  py[1],
px[2],  i*2,  py[2],
px[3],  i*2,  py[3]);
}

for (int i=-60;i<60;i++)
{
px[0] = -100;                                             py[0] = -50+sin(i*PI/60.0)*25;
px[1] =  -80+sin(i*PI/45.0)*50;   py[1] = 50;
px[2] =   80;                                                py[2] = 50;
px[3] =  100+sin(i*PI/60.0)*25;  py[3] = -50+sin(i*PI/40.0)*15;

bezier(px[0],    i*2,     py[0],
px[1 ],    i*2+sin(i*PI/120.0)*150,  py[1],
px[2],    i*2,     py[2],
px[3],    i*2,     py[3]);
}

Oczywiście jest to arbitralna zabawa liczbami i wyrażeniami matematycznymi, więc można dodawać i odejmować różne części wyrażeń, żeby uzyskać podobny, lub zupełnie inny efekt (np pionową fasadę zamiast poziomego dachu) – ale to już zależy od inwencji designera.

Aby zapisać tak wygenerowany ‘dach’ musimy użyć biblioteki do eksportowania geometrii do plików DXF. Tak samo jak w poprzednim odcinku, zadeklarujemy użycie tej biblioteki na samym początku programu poprzez dodanie linii

import processing.dxf.*;

Aby rozpocząć ‘łapanie’ geometrii przeznaczonej do zapisania na dysku, dodajemy linię
beginRaw(DXF, “dach.dxf”);
zaraz po linii
void draw()
{

a na samym końcu programu dodajemy endRaw(); (tuż przed nawiasem kończącym program)
}

Działający w przeglądarce powyższy przykład wraz z pełnym kodem można obejrzeć tutaj (wymagana zainstalowana Java).

Geometria zostanie zapisana w pliku ‘dach.dxf’ w tym samym folderze, w którym znajduje się nasz szkic (dobrze jest go najpierw zapisać poprzez File >> Save w głównym menu).

Należy pamiętać, żeby używać funkcji beginRaw(..) i endRaw() tylko wtedy kiedy chcemy zapisać geometrię, inaczej będzie ona spowalniać niepotrzebnie nasz program. Poza tym warto zapisywać geometrię bez żadnych obrotów – najlepiej poprostu włączyć i wyłączyć program trzymając kursor myszki poza oknem, wtedy dach będzie leżał poziomo na płaszczyźnie XY.  Można też zamienić linie obracające układ współrzędnych na rotateX(0); rotateZ(0); , lub zupełnie je wyłączyć/skomentować za pomocą symbolu //   (początek komentarza – tekst następujący po tym symbolu jest ignorowany).

Po wyeksportowaniu geometrii do pliku, możemy otworzyć go w programie CAD i zrobić z nim co nam się żywnie podoba :)

————————————————————————————


dach02dach03

Categories: Processing Tags: , , ,

Wstęp do Processing

September 4th, 2009 38 comments

Fala zainteresowania tematyką algorytmicznego (komputacyjnego) designu nie wydaje się słabnąć, a jako że na polskiej ‘scenie’ designerskiej niewiele jest zasobów poświęconych temu zagadnieniu rozpoczynamy wątek wprowadzający w programowanie w  Processing – otwartej platformie do programowania dla designerów, architektów i grafików.

Po pierwsze – do czego może się Processing przydać w codziennej pracy designera ? Przede wszystkim do automatyzacji powtarzalnych zadań. To jednak brzmi mało zachęcająco, więc dodam, że można z powodzeniem używać Processing do definiowania najbardziej skomplikowanych form geometrycznych, takich jak np. powierzchnie dachów i fasad (z tym spotkałem się najczęściej). Tak naprawdę jednak, najwięcej korzyści przynosi użycie go do dynamicznego, i szybkiego wspomagania procesu projektowania, a szczególnie oceny poszczególnych pomysłów, i ewolucji rozwiązań. Tutaj nie chodzi już o to, żeby wygenerować jakąś formę, lecz bardziej o generowanie jej tyle razy, i w takich wariantach, żeby znaleźć jej nalepsze wcielenie (to podejście niektórzy nazywają ‘projektowaniem ewolucyjnym’, bądź ‘generatywnym’).

pulsing_cubes

przykładowy szkic z pulsującymi sześcianami

Po drugie – Processing daje dużą dozę interaktywności. Przede wszystkim w samym procesie projektowania, gdzie możemy oglądać generowaną formę/obiekt podczas jego ewolucji  i na nią wpływać poprzez np. klawiaturę albo myszkę. Możemy także w stosunkowo prosty sposób tworzyć proste instalacje multimedialne reagujące na widza lub otoczenie (ale to już osobny rozdział).

I wreszcie po trzecie – Processing jest na tyle prosty, że może w nim pracować każdy, kto miał trochę do czynienia z prostą matematyką lub logiką. Ma w sobie sporo stworzonych przez użytkowników bibliotek, które pozwalają na szybkie i łatwe zapisanie efektów pracy w plikach PDF, JPG lub np. DWG (przy eksportowaniu trójwymiarowych modeli). Poza tym styl pisania programów na tej platformie jest bardziej luźny, większość ludzi pisze ‘szkice’, czyli krótkie zlepki kodu generujące ciekawe efekty, zamiast pisać wielkie skomplikowane programy-giganty.

W skrócie, środowisko to nadaje się dla twórców, którzy nie chcą spędzać długich godzin szukając sposobu na narysowanie np. krzywych Beziera, tylko wolą poprostu usiąść i widzieć gotowy efekt w ciągu kilku chwil.

—————————————————————

Dobrą rzeczą jest też to, że wokół platformy Processingu stworzyła się dość duża społeczność, która wymienia się doświadczeniami, fragmentami kodu i pomysłami.

Najwięcej ciekawych przykładów z kodem źródłowym można znaleźć na http://www.openprocessing.org/ lub na oryginalnej stronie www.processing.org , powstało też kilka ciekawych książek. Można by śmiało rzec, że Processing jest jedną z najlepszych platform edukacyjnych do nauki programowania i projektowania komputatywnego z tych istniejących na dziś dzień w internecie.

Sam program jest do ściągnięcia tutaj na zasadach General Public License (czyli za darmo).

—————————————————————

Ok, przejdźmy zatem do środowiska :

processing_diagram

Po otwarciu programu ukazuje się nam okno, jak to powyżej. Zintegrowane środowisko programowania, w skrócie IDE (z ang. Integrated Development Environment) jest dość proste, i składa się z kilku przycisków, rozwijalnego menu, okna wprowadzania i edycji kodu, oraz okna komunikatów.

Przyciski (od lewe):

START – służy uruchamianiu kodu, można też zrobić to naciskając CTRL+R, lub wybierając opcję ‘Run’ z górnego menu ‘Sketch’. Powoduje to otwarcie osobnego okna, w którym wyświetla się graficzna manifestacja naszego programu.

STOP – zatrzymuje uruchomiony szkic, i zamyka jego osobne okno

NEW – tworzy nowy (pusty) szkic

OPEN – otwiera istniejący szkic zapisany na dysku

SAVE – zapisuje bieżący szkic

EXPORT – przydatna funkcja eksportująca nasz szkic jako stronę .html z appletem Javy, który uruchamia się po jej otwarciu. Oznacza to, że można bardzo prosto udostępnić DZIAŁAJĄCY szkic internetowej publice, do oglądania w zwykłej przeglądarce internetowej (!).  Dzieje się to oczywiście po zapisaniu tak wyeksportowanego szkicu na jakimś serwerze, lub dołączeniu go do istniejącej strony internetowej.

—————————————————————————-

Pierwszy kod

Standardowo, każdy szkic uruchamia się w oknie, które ma 100 na 100 pikseli. Aby to zmienić, należy na początku programu napisać :

size(500,500);

Co powoduje zwiększenie wymiaru okna do 500 na 500 pikseli, co możemy zobaczyć po naciśnięciu przycisku START.

Zmiany koloru tła dokonujemy za pomocą polecenia

background(255,255,255);

gdzie trzy liczby w nawiasie to kolejno wartość czerwieni, zielonego i niebieskiego (Red Green Blue), w zakresie 0-255, czyli 255,255,255 da nam kolor biały.

aby narysować koło piszemy

ellipse(250,250,200,200);

gdzie pierwsze dwie liczby to współrzędne X i Y środka, a dwie następne to średnica X i średnica Y (jako, że rysujemy tak naprawdę elipsę – ale podając dwie jednakowe liczby dostajemy koło).

Należy tutaj nadmienić, że w większości języków programowania współrzędne pikseli na ekranie liczy się od lewego górnego rogu (0,0) do prawego dolnego (szerokość, wysokość). Do zmiany i przesunięcia układu współrzędnych służą polecenia translate(), scale() i rotate(), ale o tym później.

Tak więc nasz program powinien wyglądać mniej więcej tak :

size(500,500);

background(255,255,255);

ellipse(250,250,200,200);

Po naciśnięciu START ukaże nam się taki obraz :

cwiczenie01

Nic szczególnego tak naprawdę, ale czego można się spodziewać po trzech liniach kodu :)

Aby dodać trochę złożoności naszemu prostemu szkicowi, musimy posłużyć się pętlą FOR , oraz sinusoidą. Pętla jest to pewien fragment kodu, który jest wykonywany wielokrotnie (dość ciekawy opis można znaleźć tutaj).  Typowa pętla wygląda tak :

for (int i=0;i<100;i++)  { … tutaj jest kod … }

i jest nazwą używanej zmiennej (może to być k, j, m, a lub b, lub jakakolwiek nazwa, np. mojaZmienna ). 100 to ilość powtórzeń pętli, i++ to operacja wykonywana na zmiennej, ‘++’ znaczy zwiększenie wartości o jeden po każdym przebiegu, analogicznie ‘–’ powodowałoby jej zmniejszenie.

Int to typ zmiennej używanej w pętli, określający ją jako zmienną typu ‘integer’, czyli przyjmującą tylko całkowite wartości. W naszych szkicach będziemy narazie zamiennie używać tylko zmiennych int oraz float (zmiennoprzecinkowych, o większej precyzji).

Funkcję sinusoidalną możemy wykorzystać używając składnię sin(argument), gdzie argument to liczba z dowolnego zakresu, a wynik to liczba z zakresu od -1 do 1.

sin (0) = 0, sin(PI/2) = 1 itp. Podobnie używamy funkcji cos().

Przydadzą się też inne zmienne, np :

float kat = 0; (deklaracja zmiennej ‘kąt’ i nadanie jej wartości zero). Przy każdym kolejnym użyciu nie trzeba już deklarować typu zmiennej, wystarczy napisać po prostu kat = wartość;

oraz float promien; która zdefiniuje promień każdego z kółek.

spróbujmy zatem zamienić linę rysującą kółko na :

for (int i=0; i<50;i++)
{
float kat = i*PI/25.0;
float promien = sin(kat*2)*20+20;
ellipse(250+sin(kat)*200,250+cos(kat)*200,promien,promien);
}

Dla i rosnącego od 0 do 50, kąt przyjmuje wartość od 0 do 2*PI, czyli wykonuje pełny obrót. Promień zaś, arbitralnie zwiększa się i zmniejsza w zależności od zmian kąta – warto poeksperymentować tutaj wpisując różne wartości, można w bardzo łatwy sposób uzyskać bardzo ciekawe efekty graficzne !

Po naciśnięciu START naszym oczom powinna się ukazać następująca grafika :

cwiczenie02

Zaś aby trochę ją ożywić, możemy dodać też polecenie fill() zmieniające wypełnienie każdego indywidualnego kółka w pętli. Tak samo jak w background() , podajemy kolejno wartości koloru czerwonego, zielonego i niebieskiego (0-255)

fill(i*5,128+i*2.5,255-i*5);

tak więc cały kod powinien teraz wyglądać tak :

size(500,500);
background(255,255,255);

for (int i=0; i<50;i++)
{

float kat = i*PI/25.0;
float promien = sin(kat*2)*20+20;
fill(i*5,128+i*2.5,255-i*5);
ellipse(250+sin(kat)*200,250+cos(kat)*200,promien,promien);

}

a efekt tak :

cwiczenie03

Grafikę taką można zapisać jako bitmapę za pomocą polecenia saveFrame() , lub jako grafikę wektorową z użyciem biblioteki do eksportu PDF. W tym celu należy dodać deklarację użycia biblioteki :

import processing.pdf.*;

oraz dać znać szkicowi od którego momentu powinien ‘nagrywać’ grafikę i zapisywać ją w pliku PDF – robi się to za pomocą polecenia

beginRecord(PDF, “kolka.pdf”);

a kończy poleceniem

endRecord();

tak więc cały kod wygląda teraz tak :

import processing.pdf.*;

size(500,500);
background(255,255,255);

beginRecord(PDF, “kolka.pdf”);

for (int i=0; i<50;i++)
{

float kat = i*PI/25.0;
float promien = sin(kat*2)*20+20;
fill(i*5,128+i*2.5,255-i*5);
ellipse(250+sin(kat)*200,250+cos(kat)*200,promien,promien);

}

endRecord();

wygenerowany plik PDF można obejrzeć tutaj

————————————————————————–

Trzeba pamiętać, że kod zaprezentowany powyżej jest tylko jednym z dwóch sposobów pisania programów w Processing, gdyż do pisania aplikacji interaktywnych bardziej stosowny będzie układ zapętlony, gdzie program rysuje/tworzy grafikę lub trójwymiarowy model wiele razy na sekundę, pozwalając nam na interakcję.

O tym jednak w następnym odcinku.

Processing

June 7th, 2009 72 comments

Całkiem niedawno, na fali zainteresowania nowymi technikami tworzenia algorytmicznego designu powstał polski portal o Processing, bardzo prostym języku programowania dla architektów i designerów. Można za jego pomocą tworzyć interaktywne prezentacje multimedialne, instalacje (np. z użyciem Arduino) , projekty graficzne, trójwymiarowe formy i symulacje. Sam program jest darmowy (licencja open source) i posiada bardzo dużą bazę prostych przykładów. Do ściągnięcia na www.processing.org.

Poniżej załączam animację kilku technik parametrycznych i generatywnych, stworzonych z użyciem GC i Processing. Niektórzy ludzie spekulują, że projektowanie parametryczne nie jest do końca powiązane z generatywnym podejściem, dlatego załączam tą animację – pokazuje ona dość dobrze jak procesy generatywne ‘informują’ parametryczne komponenty (np wiklina, lub tuby tworzące tetrahedrony – czworoboki foremne) i dopełniają siebie nawzajem.
Oczywiście projektowanie parametryczne może istnieć bez generatywnego, a także generatywne bez, lub jedynie z niewielką pomocą projektowania parametrycznego – ale uważam, że to dwa komplementarne procesy.

A’propo generatywności, wśrod linków wideo wyświetlonych po powyższej animacji można znaleźć animację procesu tworzenia pola wektorów za pomocą cząsteczek (agentów), które tworzą ślady swoich trajektorii, stworzoną w Processing 1.0.3. Grafika została użyta na okładkę magazynu ‘Grafik’ (wydanie czerwiec 2009).
Program używa takich technik jak flocking (grupowanie w ‘stada’) i prostą sztuczną inteligencję.

Categories: Processing Tags: