Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Processing 2 Creative Coding Hotshot.pdf
Скачиваний:
10
Добавлен:
17.03.2016
Размер:
5.28 Mб
Скачать

Logfile Geo-visualizer

Interactive Red Dot Fever

For this final task of our current project, we will use the rotating neon globe we created for our last project. We will replace our red pins with yellow lines that stick out of our globe. These yellow pins also work very well with our shader-based filter that creates a neon representation.

Engage Thrusters

Let's add our pins to a globe:

1.Open the sketch we created in the previous task of this mission and the final sketch from our last mission. If you didn't follow the last mission, you can also download the sketch from www.packtpub.com/support.

2.In the neon globe sketch, select the Sketch | Add File... menu and open the data folder.

3.Add the two GLSL files and the images to our Red Dot Fever sketch.

4.Now add a PImage variable for the mission textures, a PShape variable for our globe, and the two PShader variables for the blur and the edge detection filter.

PImage world;

PImage bluemarble;

PImage night;

PShape pin;

PShape sphere;

PShader blur;

PShader edge;

LogRow[] data;

int LOADING = 0; int LOGFILE = 1; int GEOCODING = 2; int DONE = 3;

int state = LOADING;

int count = 0; int total = 0; float a =0;

5.We now create a new method named initGlobe() and call it from our setup() method. We also change the size of our sketch to 400 by 450 pixels and enable the P3D rendering mode.

void setup() { size(400, 450, P3D);

208

Project 8

pin = loadShape( "pin.svg" ); world = loadImage( "world.png" );

frameRate(25);

initGlobe();

Thread t = new Thread() { public void run() {

state = LOADING;

ipdatabase = parseIpDatabase( "hip_ip4_city_lat_lng.csv" ); state = LOGFILE;

String[] log = loadStrings( "access.log" ); data = parseLogfile( log );

state = GEOCODING; geoCode( data ); state = DONE;

}

};

t.start();

}

void initGlobe() {

}

6.Copy the initialization code from the setup() method of the neon globe sketch to the new initGlobe() method.

void initGlobe() {

PGraphics g = createGraphics( 700, 349); g.beginDraw();

PImage tmp = loadImage( "world.png" ); tmp.filter(INVERT);

g.tint(100, 255, 0); g.image( tmp, 0, 0 ); g.endDraw();

world = createGraphics( 700, 349 ); world = g.get(0, 0, 700, 349);

bluemarble = loadImage( "bluemarble.jpg" ); night = loadImage( "night.jpg" );

sphere = makeSphere( 150, 5, world);

edge = loadShader("edges.glsl"); blur = loadShader("blur.glsl");

}

209

Logfile Geo-visualizer

7.Now we need to copy the makeSphere() and keyPressed() methods to our new sketch.

PShape makeSphere( int R, int step, PImage tex) {

PShape s = createShape();

s.beginShape(QUAD_STRIP); s.texture( tex ); s.stroke(0, 0, 255); s.strokeWeight( 2 );

for ( int i = 0; i < 180; i+=step ) { float sini = sin( radians( i )); float cosi = cos( radians( i ));

float sinip = sin( radians( i + step )); float cosip = cos( radians( i + step ));

for ( int j = 0; j <= 360; j+=step ) { float sinj = sin( radians( j )); float cosj = cos( radians( j ));

float sinjp = sin( radians( j + step )); float cosjp = cos( radians( j + step ));

s.normal( cosj * sini, -cosi, sinj * sini);

s.vertex( R * cosj * sini, R * -cosi, R * sinj * sini, tex.width-j * tex.width / 360, i * tex.height / 180);

s.normal( cosj * sinip, -cosip, sinj * sinip);

s.vertex( R * cosj * sinip, R * -cosip, R * sinj * sinip, tex.width-j * tex.width / 360, (i + step ) * tex.height /

180);

}

}

s.endShape(); return s;

}

boolean satelite = false; void keyPressed() {

if ( key == '1' ) {

satelite = false;

sphere = makeSphere( 150, 5, world);

}

else if ( key == '2' ) {

210

Project 8

sphere.setTexture( bluemarble ); sphere.setStroke(false); satelite = true;

}

else if ( key == '3' ) { sphere.setTexture( night ); sphere.setStroke(false); satelite = true;

}

}

8.In our draw() method, we need to switch between 2D and 3D drawing, because we want our progress bar and our timeline to be drawn on top of the rotating globe. To make this work, we need to disable the 3D depth sorting before our globe gets drawn and disable it afterward.

void draw() { background(0); hint(ENABLE_DEPTH_TEST); drawGlobe(); hint(DISABLE_DEPTH_TEST); noLights();

if ( state < DONE ) { stroke( 0, 200 ); strokeWeight(2); fill( 200, 200 );

rect( 25, 150, 350, 50 ); noStroke();

fill( 255 );

rect( 30, 155, map( count, 0, total, 0, 340 ), 40 );

fill( 0 ); String msg="";

if ( state == LOADING ) {

msg = "loading database ...";

}

else if ( state == LOGFILE ) { msg = "parsing logfile ...";

}

else if ( state == GEOCODING ) { msg = "geocoding ip adresses ...";

}

text( msg, 35, 190 );

}

211

Logfile Geo-visualizer

fill(255, 0, 0);

if (state == DONE) { noStroke(); fill(0);

rect(0, 400, width, 50); stroke(255, 255, 0, 5);

long mints = data[0].timestamp;

long maxts = data[ data.length-1].timestamp; for ( int i=0; i<data.length; i++) {

float pos = map( data[i].timestamp, mints, maxts, 0, width ); line( pos, 400, pos, 450 );

}

}

9.Now add a new method named drawGlobe() and add the code that rotates and draws our globe.

void drawGlobe() { pushMatrix();

translate( width/2, (height-50)/2);

lights();

pushMatrix();

rotateX( radians(-30)); rotateY( a );

a+= 0.01;

shape(sphere);

popMatrix();

popMatrix();

if ( !satelite ) { filter(edge); filter(blur);

}

}

10.So far, our globe and the progress bar have been drawn, but we still need to add our geocoded data. We will create short yellow neon pins for our globe. Add a drawPin() method and call it from our drawGlobe() method.

void drawGlobe() { pushMatrix();

212

Project 8

translate( width/2, (height-50)/2);

lights();

pushMatrix();

rotateX( radians(-30)); rotateY( a );

a+= 0.01;

drawPins();

shape(sphere);

popMatrix();

popMatrix();

if ( !satelite ) { filter(edge); filter(blur);

}

}

void drawPins() {

}

11.In our drawPin() method, we need to convert the latitude and longitude coordinates to match the angles we used to create our sphere. Then we draw a line from the origin of our sphere to a point slightly above the surface.

void drawPins() { float R = 160;

if (state == DONE ) { strokeWeight(2); stroke(255, 250, 0);

for ( int i=0; i<data.length; i++) { beginShape(LINES);

if ( data[i].lat != null && data[i].lon != null ) { float la = map(float(data[i].lat), 90, -90, 0, 180); float lo = map(float(data[i].lon), 180, -180, 0, 360);

float sini = sin( radians( la )); float cosi = cos( radians( la )); float sinj = sin( radians( lo )); float cosj = cos( radians( lo )); vertex(0, 0, 0);

213

Logfile Geo-visualizer

vertex( R * cosj * sini, R * -cosi, R * sinj * sini );

}

endShape();

}

}

}

12.Run the sketch, and after loading the database and encoding all the IP addresses, our map looks like the following screenshot:

Objective Complete - Mini Debriefing

For this final task of our current mission, we have combined our Red Dot Fever and our neon globe from Project 7, The Neon Globe. We added the textures and the code of our GLSL filters to our sketch and copied the setup code of our globe to a method named

initGlobe().

Then we added the makeSphere() and keyPressed() methods to our sketch. In the draw() method, we had to enable the depth sorting before drawing our globe, and deactivate it before drawing our loading progress bar and the timeline. We moved the code for drawing and rotating the globe to a separate method named drawGlobe().

Finally, we added a method named drawPins() that converts the geo-coordinates of our log lines to the polar coordinates we used to create our sphere and then draws a line for each of them starting at the origin of our sphere and ending shortly above the surface of our globe.

214

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]