No description provided
The showcase player uses a modified version of Processing.js in combination with jsweet to let students program their apps in Java code while still allowing for browser support.
Content created by students is scaled to fit the showcase frame while maintaining aspect ratio and cursor position. This is why some projects may appear blurry in fullscreen, or why some small details may not be visible on a small screen
<iframe width='500px' height='400px' src='https://nest.ktbyte.com/nest#97061' allowfullscreen></iframe>
// 3D Earthquake Data Visualization V2, Processing.JS version // By: Niels J-L // Date: May 12, 2018 // // Originally: Coding Challenge #058: 3D Earthquake Data Visualization // By: Daniel Shiffman, http://codingtra.in // Date: February 20, 2017 // Video: https://www.youtube.com/watch?v=dbs4IYGfAXc // // Earthquake data (CSV format) gathered from USGS web site: // https://earthquake.usgs.gov/earthquakes/search/ // // Version 2 - Using less data M6.0+, instead of M5.0+ /* @pjs preload="land_shallow_topo_1024_inverted.jpg"; */ float angleY = 0.0; float angleZ = 0.0; float angleZdir = 0.003; //Table quakeTable; float r = 275; // Radius of globe PImage earth; PShape globe; Earthquake[] listOfQuakes; void setup() { String table[]; size(800, 800, P3D); earth = loadImage("https://www.openprocessing.org/sketch/549624/files/land_shallow_topo_1024_inverted.jpg"); // Processing.JS does not support loadTable() yet! //table = loadTable("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_day.csv", "header"); //table = loadTable("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv", "header"); //table = loadTable("all_2010s_M5plus.csv", "header"); //int rowNum = quakeTable.getRowCount(); //listOfQuakes = new Earthquake[rowNum]; // Note: When using loadStrings() the first line is the header so ignore it! table = loadStrings("https://www.openprocessing.org/sketch/549624/files/all_2000s_M6plus.csv"); int rowNum = table.length; listOfQuakes = new Earthquake[rowNum - 1]; //println("# earthquakes = " + rowNum); // Create the earthquake objects [using loadTable()] //int i = 0; //for (TableRow row : table.rows()) { // float lat = row.getFloat("latitude"); // float lon = row.getFloat("longitude"); // float mag = row.getFloat("mag"); // listOfQuakes[i] = new Earthquake(mag, lat, lon); // i++; //} // Create the earthquake objects [using loadStrings()] for (int i = 1; i < rowNum; i++) { String[] tokens = split(table[i], ","); // 4 - mag, 1 - latitude, 2 - longtitude listOfQuakes[i - 1] = new Earthquake(Float.parseFloat(tokens[4]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2])); } noStroke(); //globe = createShape(SPHERE, r); //globe.setTexture(earth); frameRate(12); } void draw() { background(15); lights(); fill(255, 255, 0, 127); textSize(20); textAlign(CENTER); text("M6.0+ Earthquakes from Jan. 2000 to May 2018", width / 2, 30); textSize(12); textAlign(LEFT); text("fps :" + int(frameRate), 10, 30); translate(width / 2, height / 2); rotateY(angleY); angleY += 0.005; rotateZ(angleZ); if ( (angleZ < 0.0) || (angleZ > PI / 4.0) ) angleZdir *= -1.0; angleZ += angleZdir; fill(200); noStroke(); //sphere(r); //shape(globe); makeSphere(r, earth); for (Earthquake q : listOfQuakes) { q.drawQuake(); } } class Earthquake { float lat; // Latitude float lon; // Longitude float mag; // Magnitude float theta; // Based on latitude float phi; // Based on longitude PVector pos; // 3D cartesian coords for position float h; // Height on globe // Constructor Earthquake(float magnitude, float latitude, float longitude) { mag = magnitude; lat = latitude; lon = longitude; float theta = radians(lat); // Latitude is between -180 and 180 deg float phi = radians(lon) + PI; // In OpenGL: y & z axes are flipped from math notation of spherical coordinates float x = r * cos(theta) * cos(phi); float y = -r * sin(theta); float z = -r * cos(theta) * sin(phi); pos = new PVector(x, y, z); h = pow(10, mag); } void drawQuake() { float maxh = pow(10, 7); float boxh = map(h, 0, maxh, 10, 100); PVector xaxis = new PVector(1, 0, 0); float angleb = PVector.angleBetween(xaxis, pos); PVector raxis = xaxis.cross(pos); pushMatrix(); translate(pos.x, pos.y, pos.z); rotate(angleb, raxis.x, raxis.y, raxis.z); fill(255, 255, 255, 127); box(boxh, 1, 1); popMatrix(); } } // makeSphere() code from Darby Rathbone's "textured sphere" // see: https://www.openprocessing.org/sketch/97273 void makeSphere(float mag, PImage pg) { float x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4; float hd = 14; float vd = 14; noStroke(); //pg.noStroke(); beginShape(QUADS); //texture(pg.get()); texture(pg); for (int i = 0; i < (2.0 * vd); i++) { for (int j = 0; j < hd; j++) { x1 = cos(i/vd*PI*1.0); x1 *= mag*sin(j/hd*PI); x2 = cos((i+1)/vd*PI*1.0); x2 *= mag*sin(j/hd*PI); x3 = cos(i/vd*PI*1.0); x3 *= mag*sin((j+1)/hd*PI); x4 = cos((i+1)/vd*PI*1.0); x4 *= mag*sin((j+1)/hd*PI); y1 = cos(j/hd*PI); y1 *= mag; y2 =cos(j/hd*PI); y2 *= mag; y3 =cos((j+1)/hd*PI); y3 *= mag; y4 =cos((j+1)/hd*PI); y4 *= mag; z1 = sin(i/vd*PI*1.0); z1 *= mag*sin(j/hd*PI); z2 = sin((i+1)/vd*PI*1.0); z2 *= mag*sin(j/hd*PI); z3 = sin(i/vd*PI*1.0); z3 *= mag*sin((j+1)/hd*PI); z4 = sin((i+1)/vd*PI*1.0); z4 *= mag*sin((j+1)/hd*PI); vertex(x1, y1, z1, i/vd*pg.height, j/(hd*2.0)*pg.width); vertex(x3, y3, z3, i/vd*pg.height, (j+1)/(hd*2.0)*pg.width); vertex(x4, y4, z4, (i+1)/vd*pg.height, (j+1)/(hd*2.0)*pg.width); vertex(x2, y2, z2, (i+1)/vd*pg.height, j/(hd*2.0)*pg.width); } } endShape(); }