IL 2016 SS
//WorldVis///////////////////////////////////////////////////////////////////////////////
//A generic tool to display some cuantitative data onto Earth surface////////////////////
//Inspired by Flink Labs visualization on climate change:////////////////////////////////
//www.flinklabs.com/projects/climatedata/////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
//This example display most populated metropolis (on this world :-)//////////////////////
//Data: cityPopulation + geoNames////////////////////////////////////////////////////////
//http://es.wikipedia.org/wiki/Anexo:Aglomeraciones_urbanas_m%C3%A1s_pobladas_del_mundo//
/////////////////////////////////////////////////////////////////////////////////////////
//Custom image based on work from [http://commons.wikimedia.org/wiki/User:Thesevenseas]//
//Font-family: Lato // Author: Lukasz Dziedzic///////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////Ale González · 60rpm.tv/i
/////////////////////////////////////////////////////////////////////////////Pubic Domain
/////////////////////////////////////////////////////////////////////////////////////////
import peasy.*;
import peasy.org.apache.commons.math.*;
import peasy.org.apache.commons.math.geometry.*;
import peasy.test.*;
PeasyCam camera;
Globe globe;
void setup() {
size(900, 700, P3D);
camera = new PeasyCam(this, 700);
frameRate(30);
cursor(CROSS);
textMode(SCREEN);
globe = new Globe(250, 24, "LDEM_16.jpg");
}
void draw() {
background(120);
lights();
//fill(WORLD_TINT);
globe.render();
}
class Globe {
PImage txtMap;
int globeRadius;
float rWRatio, rHRatio;
// Textured sphere implementation
float[][]
texturedSphereX,
texturedSphereY,
texturedSphereZ,
texturedSphereU,
texturedSphereV;
int texturedSphereDetail;
Globe(int _radius, int _sphereDetail, String _mapFilename) {
globeRadius = _radius;
txtMap = loadImage(_mapFilename);
rWRatio= txtMap.width/globeRadius;
rHRatio= txtMap.height/globeRadius;
setTexturedSphereDetail(_sphereDetail);
}
//Set the detail level for textured spheres, constructing the underlying vertex and uv map data
void setTexturedSphereDetail(int detail) {
if (detail == texturedSphereDetail) return;
texturedSphereDetail = detail;
float step = PI / detail;
float ustep = .5 / detail;
float vstep = 1. / detail;
int d1= detail+1;
int d2= detail*2 +1;
texturedSphereX = new float[d1][d2];
texturedSphereY = new float[d1][d2];
texturedSphereZ = new float[d1][d2];
texturedSphereU = new float[d1][d2];
texturedSphereV = new float[d1][d2];
for (int i = 0; i <= detail; i++) {
float theta = step * i;
float y = cos(theta);
float sin_theta = sin(theta);
float v = 1.0f - vstep * i;
for (int j = 0; j <= 2 * detail; j++) {
float phi = step * j;
float x = sin_theta * cos(phi);
float z = sin_theta * sin(phi);
float u = 1.0f - ustep * j;
texturedSphereX[i][j] = x * globeRadius;
texturedSphereY[i][j] = y * globeRadius;
texturedSphereZ[i][j] = z * globeRadius;
texturedSphereU[i][j] = u * txtMap.width;
texturedSphereV[i][j] = v * txtMap.height;
}
}
}
// draw the sphere
void render() {
noStroke();
int nexti, t2= 2*texturedSphereDetail;
//
for (int i = 0; i < texturedSphereDetail; i=nexti) {
nexti = i + 1;
beginShape(QUAD_STRIP);
texture(txtMap);
for (int j=0; j<=t2; j++) {
float u = texturedSphereU[i][j];
float x1 = texturedSphereX[i][j];
float y1 = texturedSphereY[i][j];
float z1 = texturedSphereZ[i][j];
float v1 = texturedSphereV[i][j];
float x2 = texturedSphereX[nexti][j];
float y2 = texturedSphereY[nexti][j];
float z2 = texturedSphereZ[nexti][j];
float v2 = texturedSphereV[nexti][j];
vertex(x1, y1, z1, u, v1);
vertex(x2, y2, z2, u, v2);
}
endShape();
}
}
}