Created
February 10, 2025 21:02
-
-
Save companje/9a87b68c5d05341c75842fa6a7c882d3 to your computer and use it in GitHub Desktop.
Globe Weather API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.math3.geometry.euclidean.threed.Rotation; | |
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; | |
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; | |
Vector3D focusPoint = latLonToVector3D(0, 0); | |
Vector3D nl = latLonToVector3D(52.37, 4.91); | |
Vector3D ny = latLonToVector3D(40.79, -73.96); | |
Vector3D jp = latLonToVector3D(36.14, 137.86); | |
Vector3D north = latLonToVector3D(90, 0); | |
Vector3D south = latLonToVector3D(-90, 0); | |
Vector3D india = latLonToVector3D(8.2, 77.45); | |
Vector3D points[] = {nl, ny, india, jp}; | |
Vector3D targetPoint = nl; | |
Rotation qTo = getRotationToPoint(targetPoint); | |
Rotation qNow = new Rotation(focusPoint, 0); | |
double zRotation; | |
int currentPointIndex = 0; | |
PShape sphere; | |
PImage icon; | |
void setup() { | |
size(800, 800, P3D); | |
noStroke(); | |
sphere = createShape(SPHERE, height/2); | |
sphere.rotateY(HALF_PI); | |
sphere.setTexture(loadImage("oneday_20073561211.jpg")); | |
sphere.setStroke(false); | |
} | |
void draw() { | |
background(0); | |
lights(); | |
ortho(); | |
translate(width/2, height/2); | |
qNow = interpolateRotations(qNow, qTo, .1); | |
applyRotation(qNow); | |
shape(sphere); | |
for (Vector3D p : points) { | |
pushMatrix(); | |
translate((float)p.getX() * height/2, (float)p.getY() * height/2, (float)p.getZ() * height/2); | |
fill(p==targetPoint ? 255 : 0, p==targetPoint ? 0 : 255, 0); | |
sphere(10); | |
fill(255); | |
if (icon!=null && p==targetPoint) { | |
translate(-icon.width/2, -icon.height/2); | |
image(icon, 0,0); | |
} | |
popMatrix(); | |
} | |
} | |
void applyRotation(Rotation rotation) { | |
double[][] m = rotation.getMatrix(); | |
applyMatrix( | |
(float) m[0][0], (float) m[1][0], (float) m[2][0], 0, | |
(float) m[0][1], (float) m[1][1], (float) m[2][1], 0, | |
(float) m[0][2], (float) m[1][2], (float) m[2][2], 0, | |
0, 0, 0, 1); | |
} | |
void keyPressed() { | |
if (key == ' ') { | |
currentPointIndex = (currentPointIndex + 1) % points.length; | |
targetPoint = points[currentPointIndex]; | |
qTo = getRotationToPoint(targetPoint); | |
float lat = (float)vector3DToLatLon(targetPoint).getX(); | |
float lon = (float)vector3DToLatLon(targetPoint).getY(); | |
JSONObject data = loadJSONObject("https://api.openweathermap.org/data/2.5/weather?lat="+lat+"&lon="+lon+"&appid=YOUR_APIKEY&units=metric"); | |
//println(data); | |
println("name: ", data.getString("name"), data.getJSONObject("sys").getString("country")) ; | |
JSONObject mainObject = data.getJSONObject("main"); | |
println("temperatuur: "+mainObject.getFloat("temp_min") + "°C"); | |
println("gevoelstemperatuur: "+mainObject.getFloat("feels_like") + "°C"); | |
println("minimum temperatuur: "+mainObject.getFloat("temp_min") + "°C"); | |
println("maximum temperatuur: "+mainObject.getFloat("temp_max") + "°C"); | |
println("vochtigheid: "+mainObject.getFloat("humidity")); | |
//println(mainObject); | |
JSONObject weatherObject = data.getJSONArray("weather").getJSONObject(0); | |
String iconFilename = "weather-icons/" + weatherObject.getString("icon") + "[email protected]"; | |
https://openweathermap.org/img/wn/[email protected] | |
icon = loadImage(iconFilename); | |
println(weatherObject.getString("description")); | |
println(weatherObject.getString("main")); | |
} else { | |
float step = 50; | |
if (key=='[') qTo = qTo.compose(new Rotation(focusPoint, step), RotationConvention.VECTOR_OPERATOR); | |
if (key==']') qTo = qTo.compose(new Rotation(focusPoint, -step), RotationConvention.VECTOR_OPERATOR); | |
} | |
if (key=='x') { | |
qTo = qTo.compose(new Rotation(focusPoint, -zRotation), RotationConvention.VECTOR_OPERATOR); | |
} | |
} | |
double getZRotationAngle(Rotation rotation) { | |
double[][] m = rotation.getMatrix(); // Haal de rotatiematrix op | |
return Math.atan2(m[1][0], m[0][0]); // Bereken de yaw (rotatie rond de Z-as) atan2(sinYaw, cosYaw) | |
} | |
Rotation getRotationToPoint(Vector3D point) { | |
Vector3D initialAxis = Vector3D.crossProduct(focusPoint, point); | |
if (initialAxis.getNorm() == 0) { | |
initialAxis = new Vector3D(1, 0, 0); // Kies een willekeurige as als zero en point gelijk zijn | |
} | |
initialAxis = initialAxis.normalize(); | |
double initialAngle = Math.acos(Vector3D.dotProduct(focusPoint, point)); | |
Rotation rotationToPoint = new Rotation(initialAxis, initialAngle); // Eerste rotatie: Brengt targetPoint naar voren | |
zRotation = getZRotationAngle(rotationToPoint); //, focusPoint); | |
rotationToPoint = rotationToPoint.compose(new Rotation(focusPoint, -zRotation), RotationConvention.VECTOR_OPERATOR); | |
return rotationToPoint; | |
} | |
void mouseDragged() { | |
Vector3D from = getMouseOnSphere(pmouseX, width-pmouseY); | |
Vector3D to = getMouseOnSphere(mouseX, width-mouseY); | |
drag(from, to); | |
} | |
void drag(Vector3D from, Vector3D to) { | |
Vector3D axis = Vector3D.crossProduct(from, to); | |
if (axis.getNorm() > 0) { | |
axis = axis.normalize(); | |
double angle = -Math.acos(Vector3D.dotProduct(from, to)); | |
qTo = qTo.compose(new Rotation(axis, angle), RotationConvention.VECTOR_OPERATOR); | |
} | |
} | |
Vector3D getMouseOnSphere(float x, float y) { | |
x = map(x, 0, width, -1, 1); | |
y = map(y, 0, height, 1, -1); | |
float r = x*x+y*y; | |
return new Vector3D(x, y, r>1 ? 0 : sqrt(1-r)).normalize(); | |
} | |
Rotation interpolateRotations(Rotation start, Rotation end, float t) { | |
return new Rotation(start.getQ0() + t * (end.getQ0() - start.getQ0()), | |
start.getQ1() + t * (end.getQ1() - start.getQ1()), | |
start.getQ2() + t * (end.getQ2() - start.getQ2()), | |
start.getQ3() + t * (end.getQ3() - start.getQ3()), | |
true); | |
} | |
Vector3D latLonToVector3D(float lat, float lon) { //in degrees | |
float x = cos(radians(lat)) * sin(radians(lon)); | |
float y = -sin(radians(lat)); | |
float z = cos(radians(lat)) * cos(radians(lon)); | |
return new Vector3D(x, y, z); | |
} | |
Vector2D vector3DToLatLon(Vector3D v) { | |
float lat = -degrees(asin((float)v.getY())); | |
float lon = degrees(atan2((float)v.getX(), (float)v.getZ())); | |
return new Vector2D(lat, lon); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment