Skip to content

Instantly share code, notes, and snippets.

@companje
Created September 24, 2014 13:31
Show Gist options
  • Save companje/ae60f089e1925cc6959a to your computer and use it in GitHub Desktop.
Save companje/ae60f089e1925cc6959a to your computer and use it in GitHub Desktop.
getting Longitude/Latitude when clicking on a rotated sphere
#include "ofMain.h"
class ofApp : public ofBaseApp {
public:
ofImage earth;
ofQuaternion qTo;
float angle;
ofVec3f axis;
ofPoint green;
void setup() {
ofBackground(0);
ofSetFrameRate(30);
ofDisableArbTex();
ofEnableDepthTest();
earth.loadImage("earth.jpg");
}
void draw() {
ofSetupScreenOrtho(-1,-1,0,500);
ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
ofScale(-1,-1,1);
qTo.getRotate(angle,axis);
ofRotate(angle, axis.x, axis.y, axis.z);
earth.bind();
ofScale(1,-1,1);
ofDrawSphere(250);
earth.unbind();
ofPoint c = getCartesian(qTo);
float lat = ofRadToDeg(asin(c.y));
float lon = ofRadToDeg(-atan2(c.z,c.x))-90;
if (lon<-180) lon+=360;
float x = ofMap(lon,-180,180,0,256);
float y = ofMap(lat,90,-90,0,128);
ofSetupScreen();
ofDrawBitmapString("lat: " + ofToString(lat,2),20,190);
ofDrawBitmapString("lon: " + ofToString(lon,2),20,210);
ofDisableDepthTest();
earth.draw(0,0,256,128);
ofFill();
ofSetColor(255,0,0);
ofCircle(x,y,2);
ofSetColor(0,255,0);
ofCircle(green,2);
ofSetColor(255);
ofEnableDepthTest();
}
ofVec3f getCartesian(ofQuaternion &q, ofVec4f v = ofVec4f(0,0,-1,0)) {
ofMatrix4x4 m;
q.get(m);
return m*v;
}
void mouseDragged(int x, int y, int button){
ofPoint from(ofGetPreviousMouseX(), ofGetPreviousMouseY());
ofPoint to(ofGetMouseX(), ofGetMouseY());
from = toSphere(from / ofGetWidth() - 0.5f);
to = toSphere(to / ofGetWidth() - 0.5f);
ofPoint axis = from.crossed(to);
qTo *= ofQuaternion(axis.x,axis.y,axis.z,from.dot(to));
}
void mouseReleased(int x, int y, int button) {
ofPoint vTo(ofGetMouseX(), ofGetMouseY());
vTo = toSphere(2.0*(vTo/ofGetWidth()-0.5f));
ofPoint c = getCartesian(qTo,-vTo);
float lat = ofRadToDeg(asin(c.y));
float lon = ofRadToDeg(-atan2(c.z,c.x))-90;
if (lon<-180) lon+=360;
x = ofMap(lon,-180,180,0,256);
y = ofMap(lat,90,-90,0,128);
green.set(x,y);
}
ofPoint toSphere(ofPoint v) { //-0.5 ... +0.5
float mag = v.x*v.x + v.y*v.y;
if (mag>1.0f) v.normalize();
else v.z = sqrt(1.0f - mag);
return v;
}
};
int main() {
ofSetupOpenGL(500,500,OF_WINDOW);
ofRunApp(new ofApp());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment