Bernhard Häussner
Journal: Neueste Artikel erscheinen hier (Seite 13 von 23)

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

Shortlinks implementiert

22.05.2009, 20:09

Da mein Domainname doch recht lang zu tippen ist, und sich für twitter sowieso kurze URLs gut eigenen, habe ich jetzt auf dieser Seite die meisten Seiten mit kurz-URLs ausgerüstet. So kann man jetzt z.B. mit meinem ShortURL Auto-Discovery Twitter Bookmarklet ohne Probleme Links auf diese Seite posten und man muss nur noch 1-co.de in die Adressleiste tippen, um auf die Startseite zu kommen.

Die Shortlinks werden auf den entsprechenden Seiten mit dem HTML-Tag <link rel="shortlink" href="http://1-co.de/bj" /> und mit dem HTTP-Header Link: <http://1-co.de/bj>; rel=shortlink ausgewiesen.

Hauptsächlich möglich wird das durch ein paar manuelle Einträge in der .htaccess und durch diese zwei bzw. vier netten Helfer-Funktionen (PHP), die Zahlen (int) in Zeichenfolgen (Strings) umwandeln, wodurch sie rund 20-40% kürzer werden:

function toAlphaNumber($num){
  $anum = '';
  $BASE=62;
  while ($num>=1) {
    $x=$num%$BASE;
    $anum=chr2($x).$anum;
    $num=floor($num/$BASE);
  }
  return $anum;
}
function fromAlphaNumber($str){
  $BASE=62;
  $num=0;
  for ($i=0,$len=strlen($str);$i<$len;$i++) {
    $num+=uchr2($str{$i})*(pow($BASE,($len-1-$i)));
  }
  return $num;
}
function chr2($i) {
  $i+=48;
  if ($i>57) $i+=7;
  if ($i>90) $i+=6;
  if ($i>122) throw new Exception('Too high');
  $c=chr($i);
  return $c;
}
function uchr2($c){
  $i=ord($c);
  if ($i>122) throw new Exception('Too high');
  if ($i>90) $i-=6;
  if ($i>57) $i-=7;
  $i-=48;
  return $i;
}

In der .htaccess:

#manual shortening
RewriteRule ^b$ http://bernhardhaeussner.de/blog [R=301,L]
# [...]

#call a php script that redirects to the right blog post
RewriteRule ^b/([A-Za-z0-9]+)$ blogentry.php?encid=$1 [L]

Jetzt bin ich ja mal gespannt, wie viele Leute meine Posts twittern...

Für Wordpress-User (Update 2009-06-23)

Wer sich mit nichts herum ärgern will und ein ausgereiftes und einfach konfigurierbares Plugin sucht, ist mit dem Plugin Twitter Friendly Links (empfohlen von eins78) gut aufgehoben.

Für Wordpress-User & Bastler (Update 2009-06-20)

Auf Anfrage von eins78 hier noch drei Ticks für Wordpress-Blogs: Theoretisch können auch Worpress-Autoren einfach das Bookmarklet ins HTML-Markup der Seite setzten, es ist ja ein ganz normaler Link. Allerdings funktioniert es nicht ohne Javascript und es gibt folgende elegante Lösung:

Empfehlenswerter und fast genauso einfach ist es, dieses Plugin zu benutzen: Es kümmert sich nicht nur um die Erstellung von kurz-URLs und den entsprechenden Link-Tag im <head>-Bereich: Es erstellt u.a. eine globale Variable $shortlink_url in der die kurze URL gespeichert ist. Dann muss man nur noch im Template-Ordner wp-content/themes/(templatename)/ in der (index.php) folgendes in das Template setzen:

<?php if ( isset($shortlink_url) && $shortlink_url!='' ): ?>
  <a
   href="http://twitter.com/home/?status=check+out+<?php echo $shortlink_url;?>"
   rel="nofollow shortlink"
  >
  tweet this
  </a>
<?php endif; ?>

Ich habe es probeweise im default-Template direkt in das <small> gesetzt, in dem auch Datum und Autor stehen, dann wird es klein unter der Überschrift angezeigt. Die Darstellung des Links lässt sich natürlich noch anpassen. Nachteil an dem Plugin ist, dass die Weiterleitung nicht auf Anhieb funktioniert. Man müsste erst ungefähr so etwas in die .htaccess schreiben:

RewriteRule ^([0-9]+)$ ?p=$1 [R=301,L]

Eine Lösung ganz ohne Plugin hat Thomas Scholz veröffentlicht. Sie „schont die Optionstabelle und erleichtert individuelle Anpassungen“. Allerdings enthalten die Kurzlinks ?p=, weshalb die URLs nicht ganz so schön werden.

Kommentare: 7 Einträge

SchülerVZ Buschfunk verstecken Firefox Add-On

07.05.2009, 18:28

Vor kurzem hat Schülerverzeichnis eine neue „Funktion“ namens „Buschfunk“ auf die Startseite hinzugefügt, die irgendwie jeden zu nerven scheint, mich eingeschlossen. Wozu gibt es Twitter. Deshalb von mir ein Firefox-Add-On um den Buschfunk zu verstecken.

Bisher ist das Add-On noch im Sandkasten, aber falls es sich bewährt (und kompatibel mit den ganzen Mozilla-Richtlinien ist) wird es vielleicht offiziell...

Technisches

Eigentlich ist das Add-On nur ein Greasemonkey-Script, dass mit dem User Script Compiler in ein Add-On umgewandelt wurde. Für alle, die sowieso die Greasemonkey-Erweiterung installiert haben, recht es auch das User-Script zu installieren:

Viel Spaß mit der Erweiterung. Oder viel Spaß ohne Buschfunk und vielleicht mit Twitter.

Edit:

Das Add-On ist obsolet, da es inzwischen das Feature schon auf der Seite gibt.

Kommentare: 4 Einträge
 
Χρόνογραφ
© 2008-2017 by Bernhard Häussner - Impressum - Login
Kurz-Link zu dieser Seite: http://1-co.de/bj