Skip to content

Instantly share code, notes, and snippets.

@companje
Last active March 17, 2024 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save companje/e5a2584c4e66cb99e1ee7c4738ebf910 to your computer and use it in GitHub Desktop.
Save companje/e5a2584c4e66cb99e1ee7c4738ebf910 to your computer and use it in GitHub Desktop.
Rotate sphere with anchorpoint
float d, r, eyeZ = 1900;
PShape sphere;
Quaternion qTo = new Quaternion();
Quaternion qNow = new Quaternion();
PVector anchorPoint = null;
ArrayList<PVector> points = new ArrayList();
PVector center = new PVector(0, 0, 0);
PVector top = new PVector(0, 0, 1);
void settings() {
fullScreen(P3D);
}
void setup() {
noCursor();
d = height;
r = d/2;
surface.setSize((int)d, (int)d);
surface.setLocation(int(displayWidth/2-r), 0);
sphere = createShape(SPHERE, height/2);
sphere.rotateY(HALF_PI);
sphere.setTexture(loadImage("earth2.jpg"));
sphere.setStroke(false);
for (int i=0; i<20; i++) {
PVector p = PVector.random3D();
p.setMag(r);
points.add(p);
}
hint(DISABLE_OPTIMIZED_STROKE);
}
void draw() {
PVector mouse = toSphere(mouseX/r-1, mouseY/r-1);
qNow = Quaternion.slerp(1, qNow, qTo);
background(0);
perspective(atan(r/eyeZ)*2, 1, eyeZ, eyeZ*2);
camera(0, 0, -eyeZ, 0, 0, 0, 0, 1, 0);
scale(-1, 1, 1);
pushMatrix();
rotate(qNow);
shape(sphere);
//red dots that turn yellow when mouse nearby
for (PVector point : points) {
pushMatrix();
translate(point.x, point.y, point.z);
if (dist(mouseX, mouseY, screenX(0, 0, 0), screenY(0, 0, 0))<50) {
fill(255, 255, 0);
} else {
fill(255, 0, 0);
}
noStroke();
sphere(5);
popMatrix();
}
popMatrix();
//top
fill(0, 255, 255);
noStroke();
drawDot(top);
//mouse
fill(255, 255, 0);
noStroke();
drawDot(mouse);
stroke(255, 0, 255);
strokeWeight(4);
drawLine(top, mouse);
if (anchorPoint!=null) {
fill(0, 255, 0);
noStroke();
drawDot(anchorPoint);
stroke(0, 255, 255);
strokeWeight(4);
drawLine(anchorPoint, mouse);
}
}
void drawDot(PVector p) {
pushMatrix();
translate(p.x*r, p.y*r, p.z*r);
sphere(10);
popMatrix();
}
void drawLine(PVector a, PVector b) {
hint(DISABLE_DEPTH_TEST);
noFill();
beginShape();
for (int i=0, n=10; i<=n; i++) {
PVector m = a.copy().lerp(b, float(i)/n);
m.normalize();
vertex(m.x*r, m.y*r, m.z*r);
}
endShape();
hint(ENABLE_DEPTH_TEST);
}
void mouseDragged() {
drag(pmouseX, pmouseY, mouseX, mouseY);
}
void mousePressed() {
if (mouseButton==RIGHT) {
anchorPoint = toSphere(mouseX/r-1, mouseY/r-1);
}
}
void drag(PVector _from, PVector _to, PVector _anchor) { //-1..1
PVector from = _from.sub(_anchor).normalize();
PVector to = _to.sub(_anchor).normalize();
PVector axis = from.cross(to);
float half_angle = asin(from.dot(to))/2;
Quaternion q = new Quaternion(cos(half_angle), axis.x * sin(half_angle), axis.y * sin(half_angle), axis.z * sin(half_angle));
qTo.mult(q);
qTo.normalize();
}
void drag(float px, float py, float x, float y) { //0..mouseX, 0..mouseY
PVector from = toSphere(px/r-1, py/r-1);
PVector to = toSphere(x/r-1, y/r-1);
drag(from, to, anchorPoint!=null ? anchorPoint : center);
}
@companje
Copy link
Author

Globe4D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment