Bernhard Häussner
Tags: Artikel mit dem Tag «Art» durchstöbern

3D-Tagcloud mit Processing

25.05.2009, 18:55

Ich habe ja schon etwas mathematisches und recht interaktives mit Processing gemacht. Jetzt wollte ich noch eine kleine Daten-Visualisierung basteln. Da ich wenig Lust habe tagelang irgendwelche tweets zu analysieren und ich mich nicht in die Musik-Librarys von Processing einarbeiten wollte, habe ich meine Blogeinträge und die dazugehörigen Tags als Datenset hergenommen, was auch noch eine recht überschaubare Datenmenge ist, und sie in einer Art 3D-Netz angeordnet. Video:


Zunächst einmal habe ich die Daten als .csv aus der Datenbank exportiert. Dieses Dateiformat ist zum Glück einfach mit Processing einzulesen. Daraus habe ich ein paar Objekte erstellt. Hier war ich mir ein bisschen unsicher, wie das zu realisieren sei. Im Endeffekt habe ich 3 Arrays von Objekten, einer enthält alle Tags, einer alle Blogeinträge und ein dritter alle Verbindungen. Zusätzlich bekommen alle Tags noch eine ArrayList mit ihren zugeordneten Blogeinträgen, um das aktivieren (röten) einfacher zu machen.

Dann haben die 3 Objekte (Eintrag, Tag, Verbindung) erstmal jeweils eine rendering-Methode bekommen. Die Einträge und Tags zeigen einfach ihr Label an, und beginnen auf einer Ebene mit (mehr oder weniger) zufälliger Position. die Verbindungen, die jeweils einen Pointer auf einen Eintrag und einen Tag speichern, rendern sich als Linie zwischen den Positionen der beiden. Zusätzlich habe ich noch eine Szene implementiert, die von der aktuellen Framezahl die Kameraposition und das aktivierte Tag bestimmt.

Eine rein zufällige Anordnung ist allerdings nicht wirklich zufriedenstellend. Deshalb beginnen nun die Tags als nächstes sich dem Schwerpunkt ihrer zugehörigen Blogeinträge zu nähern und die Blögeinträge nähern sich dem Schwerpunkt ihrer Tags. Aus Spaß habe ich das einmal laufen lassen, natürlich kollidiert das ganze recht zielstrebig. Als zweiter Bewegungsparameter kommt hinzu, dass, wenn ein gewisser Mindestabstand unterschritten wird, sich die Blogeinträge und Tabs auch gegenseitig abstoßen. Hier musste ich die Parameter recht fein abstimmen.

Damit nicht der Expansionscharakter die Überhand bekommt (wie bei unserem Universum?), habe ich auch noch eine Arena eingeführt: Wenn die Schriftposition aus einem Zylinder in der Mitte des Bildschirms heraus wandert, greift ein „Sheepdog“, der das Bewegungsverhalten überschreibt und die Tags bzw. Einträge zurück zum Mittelpunkt zieht, bis sie wieder im Rahmen sind. Da die Blogeinträge sowieso etwas unter Druck stehen, sorgt das dafür, dass alles schön zentriert bleibt und ein bisschen in ein Raster gepresst wird.

Je nach Anfangsposition funktioniert der Algorithmus mal besser und mal schlechter, vielleicht müsste ich noch etwas an den Parametern schrauben. Es ist auch schwer zu sagen, was gut und schlecht ist, aber hin und wieder gehen Tag-Eintrag-Verbindungen über den halben Zylinder („mangelnder Ellbogen-Einsatz“?) und bei manchen Durchläufen werden z.B. einige einfache Verbindungen recht schön kurz.

Das ganze lief mit dem P3D-Renderer eigentlich ganz ordentlich, doch dank diesem Tutorial zu Additive Blending mit OpenGL wird jetzt auch mit dem OpenGL-Renderer der Text ohne die weißen Flächen in den Buchstaben gerendert. Ich musste nur alles auf schwarz umstellen, was allerdings auch nicht schlecht aussieht. Jetzt läuft die Animation mit Kantenglättung (smooht() und P3D läuft bei mir sehr sehr langsam) weich wie Butter. Und so sieht alles in schwarz aus:

Mit einer netten Textur und frei drehbar im neuen Style:

Irgendwie interessiert mich als nächstes „Magnetismus“. Man liest recht viel darüber, mal sehen was genau man sich darunter vorzustellen hat.

Kommentare: keine

Malen mit Planetenpartikeln

23.05.2009, 19:35
„Processing Red“
„Processing Red“

Nachdem ich mit Processing nach erstaunlich kurzer Zeit einen kleinen Planeten, der um die Maus kreist, hin bekommen habe, der immer mit einer Kraft proportional zur Wurzel der Entfernung angezogen wird, dachte ich mir, dass man dieses Prinzip noch etwas ausbauen kann.

Zunächst hatte ich nur den einen Planeten, dann wurden es 10. Eigentlich habe ich ihnen nur eine „Spur“ verpassen wollen, doch dann habe ich beschlossen, den Bildschirm einfach nicht nach jedem Frame zu löschen (oder z.B. mit 20% weiß zu über pinseln, sodass die Partikel eine Spur hinterlassen) sondern die Partikel einfach weiter ohne löschen zu rendern, wodurch dann Linien entstehen.

Da die ganzen Planeten/Partikel dann schwierig zu kontrollieren waren, habe ich noch die Funktion hinzugefügt, dass sie vor der Maus fliehen, wenn ich die Maustaste drücke und dann ihr Gravitationsverhalten so geändert, dass sie einen Widerstand erfahren, ähnlich Luftreibung, und nicht direkt von der Maus angezogen werden, sondern auf einem Ring in einem kleinen Abstand bleiben, damit sie nicht irgendwann alle auf der Mausposition landen, denn dann ließen sie sich nicht mehr trennen. Das sah dann so aus:

„Processing Gravity“ einer der ersten Versuche
„Processing Gravity“ einer der ersten Versuche

Jetzt wurde es Zeit etwas mehr Komplexität hinzuzufügen. Also habe ich den Hauptpartikeln noch andere Partikel delegiert, die wiederum den Hauptpartikel mit ähnlichem Gravitationsverhalten folgen. Und diese wurden dann wieder von anderen Partikeln verfolgt usw. Zuletzt hatte ich 75 Partikel die sich auf unübersichtliche Weise gegenseitig verfolgen, aber im Endeffekt immer der Maus folgen.

Außerdem haben meine Partikel noch verschiedene Renderer zugeordnet bekommen. Die Hauptpartikel blieben große schwarze Punkte (allerdings habe ich die Transparenz erhöht), die Trabanten der Hauptpartikel wurden klein und schwarz und diese wurden wiederum von hellgrünen bzw. hellroten Partikeln verfolgt.

Diese farbigen Partikel werden dann noch von Spezialpartikeln verfolgt, die sich ihre letzte Position merken und dann eine Linie zu ihrer aktuellen Position zeichnen, sodass ganz feine Linien möglich sind.

Dann musste ich noch eine Geschwindigkeitsbegrenzung einführen. Denn sonst fliegen die Trabanten zweiter und dritter Ordnung nach kurzer Zeit so schnell, dass sie nicht nur den Bildschirm weit verlassen, sondern auch keine schönen Linien mehr zeichnen. Außerdem habe ich die Startpositionen von einer einfachen Aufreihung am Bildschirmrand zu einem Raster in der Mitte der Zeichenfläche geändert, sodass der Start nicht immer zu sehen ist. Dann konnte ich anfangen zu malen:

Interessant ist auch, dass manche Kreationen trotzt reinem 2D-Rendering einen räumlichen Eindruck hinterlassen.

Die Ästhetik wird entscheidend von der Mausführung des Künstlers geprägt.

Irgendwann wurde grün langweilig...

Ich weiß natürlich dass mancher ähnliche generative Algortihmen auch mit Musik steuert o.ä. aber mit Processing auch wirklich Daten (außer der Mausbewegung) zu visualisieren, damit beschäftigt sich mein nächster Blogpost (Der Algorithmus ist schon fertig, aber ich darf erst am Donnerstag wieder ein HD-Video zu vimeo hoch laden...).

Kommentare: keine

Processing: 3D-Koch-Kurve mit Sierpinski-Dreieck

23.05.2009, 17:34

Nachdem ich mich jetzt mal an Processing heran gewagt habe, habe ich auch gleich mal einen fraktalen Körper basteln müssen. Es handelt sich um eine Art dreidimensionale Koch-Schneeflocke.

Die Koch-Schneeflocke an sich ist eigentlich recht simpel, habe ich schon in Logo und PHP implementiert. Es wird eine Linie jeweils durch eine Linie mit einem Dreieck darin ersetzt. Auf den Raum übertragen heißt das dann eine Dreieckfläche bekommt einen Tetraeder eingesetzt. Dies wird dann mit den Flächen des Tetraeders rekursiv wiederholt, sodass dann ungefähr so etwas entsteht:

Es entsteht eigentlich eine etwas andere Form, die allerdings nicht sehr interessant anzusehen ist, nämlich ein Tetraeder, der in viele kleine Tetraeder zerlegt ist. Damit der strenge Tetraeder etwas aufgelockert wird, habe ich die neuen Tetraeder immer um 70% skaliert. Es sind also keine Tetraeder mehr, sondern, je tiefer die Rekursion geht, immer schiefere Pyramiden.

Außerdem habe ich nicht mit nur einem Dreieck begonnen, sondern mit einem Tetraeder, sodass ein Körper ensteht, ähnlich wie wenn man in 2D mit dem Dreieck beginnt. Bei 6 Rekursionsschritten ergeben sich dann 66*4 = 186 624 Dreiecke. Die werden dann von Processing z.B. mit 7%iger Transparenz gerendert, damit es etwas schöner aussieht und so kann dann dieses Video entstehen:


Interessant ist eigentlich auch, dass der Rest, der vom ursprünglichen Dreieck bleibt, wenn man die ganzen Tetraeder heraus nimmt, genau dem Sierpinski-Dreieck entspricht. So sieht der Code aus:

fraqTriang trs[]=new fraqTriang[4];

void setup(){
  size(640, 480, P3D);
  noStroke();
  fill(150,150,150,20);
  int bigrad=200;
  int req=6;
  
  PVector A=new PVector(-bigrad,0,0);
  PVector B=new PVector(bigrad/2,0,-173.21);
  PVector C=new PVector(bigrad/2,0,173.21);
  PVector D=new PVector(0,-bigrad*(sqrt(6)/3),0);
  
  trs[0]=new fraqTriang(A,B,C,req);
  trs[1]=new fraqTriang(A,D,B,req);
  trs[2]=new fraqTriang(A,C,D,req);
  trs[3]=new fraqTriang(B,D,C,req);
}


void draw(){
  background(255);
  lights();
  
  float winkel=(mouseX/float(width))*TWO_PI;
  float xpos=cos(winkel);
  float ypos=sin(winkel);
  float radius=300.000;
  camera(xpos*radius, mouseY, ypos*radius, // eyeX, eyeY, eyeZ
         0.0, -50.0, 0.0, // centerX, centerY, centerZ
         0.0, -1.0, 0.0); // upX, upY, upZ
      
  for (int i=0;i<trs.length;i++) {
    trs[i].display();
  }
  //saveFrame("frames/koch3d-####.png"); //uncomment to record
}

class fraqTriang{
  PVector PointA;
  PVector PointB;
  PVector PointC;
  fraqTriang recTris[]=new fraqTriang[6];
  int rec;
  float scaling;
  
  fraqTriang(PVector A,PVector B,PVector C, int recursion){
    scaling=0.7;
    PointA=A;
    PointB=B;
    PointC=C;
    rec=recursion;
    applyRecursion ();
  }
    
  void applyRecursion () {
    if (rec!=0) {
      PVector PointAB2=PVector.add(PointA,PointB);
      PointAB2.div(2);
      PVector PointAC2=PVector.add(PointA,PointC);
      PointAC2.div(2);
      PVector PointBC2=PVector.add(PointB,PointC);
      PointBC2.div(2);
      
      PVector PointZ=PVector.add(PointA,PointB);
      PointZ.add(PointC);
      PointZ.div(3);
      PVector PointAB=PVector.sub(PointA,PointB);
      PVector PointAC=PVector.sub(PointA,PointC);
      PVector PointH=PointAB.cross(PointAC);
      PointH.normalize();
      PVector PointAAB2=PVector.sub(PointA,PointAB2);
      float a=PointAAB2.mag();
      float pheight=a*(sqrt(6)/3)*scaling;
      PointH.mult(-pheight);
      PVector PointZH=PVector.add(PointZ,PointH);
      
      recTris[0]=new fraqTriang(PointA,PointAB2,PointAC2,rec-1);
      recTris[1]=new fraqTriang(PointB,PointBC2,PointAB2,rec-1);
      recTris[2]=new fraqTriang(PointC,PointAC2,PointBC2,rec-1);
      
      recTris[3]=new fraqTriang(PointZH,PointAC2,PointAB2,rec-1);
      recTris[4]=new fraqTriang(PointZH,PointAB2,PointBC2,rec-1);
      recTris[5]=new fraqTriang(PointZH,PointBC2,PointAC2,rec-1);
    }
  }  
  
  void display () {
    if (rec==0) {
      beginShape();
      vertex(PointA.x, PointA.y ,PointA.z);
      vertex(PointB.x, PointB.y ,PointB.z);
      vertex(PointC.x, PointC.y ,PointC.z);
      endShape(CLOSE);
    } else {
      for (int i=0; i<recTris.length;i++) {
        recTris[i].display();
      }
    }
  }
  
}

Man sieht dem Code an, wie schnell man mit Processing Graphiken erstellen kann, ohne sich mit komplizierteren APIs herumzuschlagen. Durch die vielen Beispiele, die Processing beiliegen und die übersichtliche API-Dokumentation kann man innerhalb von kurzer Zeit schon recht hübsche Ergebnisse erzielen. Viel Synatax muss man auch nicht lernen, da die Processing-Synatx mehr oder weniger der von Java entspricht.

Kommentare: keine

Vektor-Wallpaper

12.04.2009, 21:01

Heute habe ich mal wieder ein bisschen mit Inkscape herum gespielt, wobei diese Interessanten Fraktal-artigen, (dreh)symmetrischen Figuren entstanden sind. Ich habe dann Details ausgewählt (und mit selektierten Farben versehen) aus diesem gesamten Set:

Da alles als SVG-Datei angelegt wurde ist es auch beliebig skalierbar. Irgendwie ruft der leicht kubistische Style nach einem Kantenfindungs-Algorithmus, der das Ganze mehr oder weniger automatisch mit Fotos macht... muss ich aber wohl vertagen.

order (custom-made) prints

Kommentare: keine

Film ohne Frames

30.03.2009, 15:55

Ich hatte die Idee eine Animation zu kreieren, die nicht auf Frames basiert, sondern bei der ein Filmstreifen mit einer langen Graphik über einen Projektor läuft.

Eigentlich hat mich schon immer der Effekt interessiert wenn man im fahrenden Zug das Auf und Ab der Oberleitung bzw. früher der Telegraphenleitung beobachtet. Als Zugfenster habe ich jetzt einfach eine Projektionsfläche eingesetzt und als Telegraphendraht ein paar eher abstrakte Formen.

Da ich nicht Projektoren und Film zum Basteln da habe, und ich das auch gerne mit dem Computer ausgleiche, ist die Idee jetzt (vielleicht zunächst) am Computer entstanden.

Technische Umsetzung

Zunächst muss man dem Computer natürlich beibringen, welche Formen am Bildschirm vorbei ziehen sollen. Da die im Endeffekt vorbei laufende Bitmap eine Größe von 1280x191250=244M Pixel hat, was im RAM auf 2,1 GB hinaus läuft, habe ich in der Planungsphase das SVG-Format benutzt. Ich konnte also mit Inkscape schön die Formen konstruieren, während meine zurzeit 6 GB RAM nicht zu sehr belastet werden.

Als nächstes habe ich dann gleich die Einzelframes gerendert. Dazu habe ich mein altbewährtes SVG-Rendering-Script vom Bilder-Züchten in stark vereinfachter Form benutzt: Es hat nur die Aufgabe 6375 Mal den SVG-Viewport etwas nach unten zu rücken und den Frame von Inkscape rastern zu lassen.

Die Musik ist, wie man vielleicht hört, ziemlich experimentell. Sie ist komplett mit dieser Webseite gemacht. Das ganze habe ich dann noch mit MPlayer zusammengefügt:

mencoder "mf://frames/*.png" -mf fps=25 -o output.avi -ovc xvid -xvidencopts bitrate=5000 -oac mp3lame -audiofile musik.wav

Und so ist dann die oben zu sehende Animation entstanden.

Tags:
Kommentare: keine
 
Χρόνογραφ
© 2008-2012 by Bernhard Häussner - Impressum - Login
Kurz-Link zur Homepage: http://1.co.de/