{"id":102,"date":"2018-09-24T12:48:59","date_gmt":"2018-09-24T12:48:59","guid":{"rendered":"http:\/\/symotiv.de\/?p=102"},"modified":"2019-04-24T14:32:09","modified_gmt":"2019-04-24T14:32:09","slug":"toolentwicklung-zur-visualisierung-der-daten","status":"publish","type":"post","link":"https:\/\/symotiv.de\/toolentwicklung-zur-visualisierung-der-daten","title":{"rendered":"05 – Toolentwicklung zur Visualisierung der Daten"},"content":{"rendered":"

Als der Arbeitsstand weit genug war, um ein fertiges Datenset mit 3D-Koordinationsdaten aufzuzeigen, mussten wir nat\u00fcrlich \u00fcberpr\u00fcfen, wie sie qualitativ ausgegeben wurden. Hierf\u00fcr eigneten sich gut die Creative Coding Frameworks Processing oder p5.js, um einen schnellen Sketch zu entwerfen, der die Daten ausplottet. Daher wurde sich f\u00fcr ein Webtool p5 entschieden, da man das einfach online einbetten und mit anderen Mitwirkenden teilen kann.<\/p>\n

Hier wurde also die .CSV eingelesen, die aus dem 3D-baseline Tool ausgegeben worden ist. Um die irrelevanten Zahlen herauszufiltern wurde folgendes Array angewandt, dass die Iteratioinsrehenfolge im Code auf die relevanten Zahlenstellen in der .CSV verweist. Hier ist wieder zu beachten, dass eine Stelle f\u00fcr 3 Zahlen (x, y, z) steht:<\/p>\n

var relevant = [
\n<\/span><\/span>0, \/\/ H\u00fcfte Mitte 0
\n<\/span><\/span>1, \/\/ H\u00fcfte Links 1
\n<\/span><\/span>2, \/\/ Knie Links 2
\n<\/span><\/span>3, \/\/ Fu\u00df Links 3
\n<\/span><\/span>\/*4,5,*\/
\n<\/span><\/span><\/span>6, \/\/ H\u00fcfte Rechts 4
\n<\/span><\/span>7, \/\/ Knie Rechts 5
\n<\/span><\/span>8, \/\/ Fu\u00df Rechts 6
\n<\/span><\/span>\/*9,10,11,*\/
\n<\/span><\/span><\/span>12, \/\/ Torso 7
\n<\/span><\/span>13, \/\/ Nacken 8
\n<\/span><\/span>14, \/\/ Hals 9
\n<\/span><\/span>15, \/\/ Kopf 10
\n<\/span><\/span>\/*,16*\/
\n<\/span><\/span><\/span>17, \/\/ Schulter Rechts 11
\n<\/span><\/span>18, \/\/ Ellbogen Rechts 12
\n<\/span><\/span>19, \/\/ Hand Rechts 13
\n<\/span><\/span>\/*20,21, 22, 23, 24,*\/
\n<\/span><\/span><\/span>25, \/\/ Schulter Links 14
\n<\/span>26, \/\/ Ellbogen links 15
\n<\/span><\/span>27 \/\/ Hand Links 16
\n<\/span><\/span>\/*,28*\/<\/span><\/span><\/span>];<\/span><\/span><\/p>\n

Es ergeben sich also die genannten 17 Stellen, die vom Sketch durch iteriert werden. Die Iteration l\u00e4uft in mehreren Schritten ab. Zun\u00e4chst wurde festgelegt, dass die Framerate des Sketches 60 Bilder pro Sekunde betr\u00e4gt, mit: frameRate(60);. Um dann in jedem Frame des Sketches auch nur einen Frame der CSV auszulesen, wurde eine Variable erstellt, die sich jeden Frame um 1 erh\u00f6ht und sich automatisch zur\u00fccksetzt, wenn die Frames der CSV Datei zuende gehen. So kann das zum Beispiel aussehen:<\/p>\n

var index = 0;
\n<\/span><\/span>var pose = out[index].split(\",\");
\n<\/span><\/span>if (index < out.length-1)
\n<\/span><\/span>index ++;
\n<\/span>else
\n<\/span><\/span>index = 0;<\/span><\/p>\n

Mit der Variablen pose wird also ein Array aufgemacht, das durch die split-Funktion und dem index-Input immer die Koordinationsdaten des aktuellen Frames beinhaltet. Das bietet die Basis, um diese Koordinaten dem 3D-Raum zuzuordnen. Ein simples Skelett der 3D-Bewegung ergibt sich nun durch den n\u00e4chsten Schritt der Iteration, indem pro Frame alle Joints des Skeletts nacheinander platziert werden. Das wird mit einer for-Schleife gemacht, die das relevant-Array abtastet. Jede Stelle aus dem relevant array muss hier verdreifacht werden, um in dreier schritten von Joint zu Joint zu kommen. SO ist 0*3 = 0, es werden also die Stellen 0, 1, 2 f\u00fcr die x, y, z Positionen des ersten Joints angesprochen; 1*3 = 3 entspricht den Stellen 3, 4, 5 und so weiter:<\/p>\n

for (j=0; j<relevant.length; j+=1)
\n<\/span><\/span>{
\n<\/span><\/span>\u00a0 var x = parseFloat(pose[relevant[j]*3]);
\n<\/span>\u00a0 var y = parseFloat(pose[relevant[j]*3+1]);
\n<\/span>\u00a0 var z = parseFloat(pose[relevant[j]*3+2]);
\n<\/span>\u00a0 translate(x, y, z);
\n<\/span>\u00a0 sphere(jointsize);
\n<\/span>}<\/span><\/span><\/p>\n

So wird eine Kugel an die 3D-Position von jedem Joint gesetzt und es ergibt sich die Grundlage f\u00fcr gestalterische Experimente. Eine einfache Variante, um die Gestaltung der CSV-Ergebnisse schnell verst\u00e4ndlich zu machen, sind Verbindungslinien, die sich von Joint zu Joint ziehen. So werden aus einzelnen schwebenden Kugeln schnell eine humanoide Form, die man verstehen kann. Dazu muss ein zweites Set x, y, z \u2013 Daten erstellt werden, um eine Linie zu zeichnen. Im folgenden Beispiel werden f\u00fcr die Joints des linken Beins (Stellen 1, 2, 3 im relevant-Array) eine Linie gezogen, die sie zum Joint verbindet, der im relevant Array eine Stelle zu vor kommt Daher relevant[j - 1]. Der Fu\u00df wird also mit dem Knie, das Knie mit der linken H\u00fcfte, und die linke H\u00fcfte mit dem Root-Joint der H\u00fcfte verbunden:<\/p>\n

for (j=0; j<relevant.length; j+=1)
\n<\/span><\/span>{
\n<\/span><\/span>\u00a0 var x = parseFloat(pose[relevant[j]*3]);
\n<\/span>\u00a0 var y = parseFloat(pose[relevant[j]*3+1]);
\n<\/span>\u00a0 var z = parseFloat(pose[relevant[j]*3+2]);<\/span><\/p>\n

\u00a0 if (j > 0 && j < 4) {
\n<\/span><\/span>\u00a0 \u00a0 var xl = parseFloat(pose[relevant[j - 1] * 3]);
\n<\/span>\u00a0 \u00a0 var yl = parseFloat(pose[relevant[j - 1] * 3 + 1]);
\n<\/span>\u00a0 \u00a0 var zl = parseFloat(pose[relevant[j - 1] * 3 + 2]);<\/span><\/p>\n

\u00a0 \u00a0 stroke(strokecolor);
\n<\/span><\/span>\u00a0 \u00a0 strokeWeight(strokeweight);
\n<\/span>\u00a0 \u00a0 line(x, y, z, xl, yl, zl);<\/span><\/p>\n

\u00a0 }<\/span><\/p>\n

\u00a0 sphere(jointsize);<\/span><\/span><\/p>\n

}<\/span><\/span><\/p>\n

Die Positionierung der Joints im Array erlaubt es leider nicht, immer mit j \u2013 1 zu verbinden, daher sind einge if-Abfragen n\u00f6tig, um die humaniode Figur zu erstellen:<\/p>\n

j \u2013 1: if (j > 0 && j < 4 ||
\n<\/span><\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0j > 4 && j < 7 ||
\n<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0j > 7 && j < 11 ||
\n<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0j > 11 && j < 14 ||
\n<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0j > 14 && j < 17)
\n<\/span>j - 4: if (j == 4)
\n<\/span><\/span>j - 7: if (j == 7)
\n<\/span><\/span>j \u2013 3: if (j == 11)
\n<\/span><\/span>j \u2013 6: if (j == 14)<\/span><\/span><\/p>\n

Dar\u00fcber hinaus kann man mit<\/p>\n

viele noch viele andere visuelle Varianten erzeugen. Zum Beispiel lassen sich mit beginShape(); und vertex() Polygone erstellen, oder mit Vektoren und dem Lerp-Befehl 3-dimensionale Zwischenschritte zwsichen den Joints generieren.<\/p>\n

Das Tool hat dem Projekt als Qualit\u00e4ts\u00fcberpr\u00fcfung und gestalterisches Concepting Tool geholfen, da die<\/span>se<\/span> Struktur, die Daten auszulesen, auch sp\u00e4ter im Projekt in C# f\u00fcr Unity eingearbeitetes werden konnte.<\/span><\/p>\n

\"\"<\/p>\n

https:\/\/www.openprocessing.org\/sketch\/578388<\/a><\/p>\n

Es wurde noch eine zweite Version des Webtools erstellt, um einen sp\u00e4teren Datensatz zu visualisieren, in dem die \u00fcberfl\u00fcssigen Werte schon rausgel\u00f6scht waren. Dazu wurde hier noch der Low-Pass Filter implementiert, der zum smoothen der Daten angewandt wurde.<\/p>\n

https:\/\/www.openprocessing.org\/sketch\/685683<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

Als der Arbeitsstand weit genug war, um ein fertiges Datenset mit 3D-Koordinationsdaten aufzuzeigen, mussten wir nat\u00fcrlich \u00fcberpr\u00fcfen, wie sie qualitativ ausgegeben wurden. Hierf\u00fcr eigneten sich gut die Creative Coding Frameworks Processing oder p5.js, um einen schnellen Sketch zu entwerfen, der die Daten ausplottet. Daher wurde sich f\u00fcr ein Webtool p5 entschieden, da man das einfach […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/posts\/102"}],"collection":[{"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/comments?post=102"}],"version-history":[{"count":7,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/posts\/102\/revisions"}],"predecessor-version":[{"id":115,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/posts\/102\/revisions\/115"}],"wp:attachment":[{"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/media?parent=102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/categories?post=102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/symotiv.de\/wp-json\/wp\/v2\/tags?post=102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}