Loading...
Logo
Processing Forum
so i have been trying to perfect spherical orbiting, what i have is a sphere located at (0, 0, 0), and a camera that rotates around it in a...spherical way. i can make rotations in the x-z plane (around) just fine but when it comes to rotating in the y-z plane (rotating towards the top or bottom of something, not around) it bugs out and won't rotate properly. I am trying to achieve the same effect as peasycam minus the enertia and fancy stuff. here is my code:

Copy code
  1. import processing.opengl.*;
  2. PVector cam;
  3. float camRadius, camTheta, camPhi;
  4. private final static float compensation = 0.05f;
  5. void setup() {
  6.   size(500, 500, OPENGL);
  7.   hint(ENABLE_OPENGL_4X_SMOOTH);
  8.   hint(DISABLE_DEPTH_TEST);
  9.   cam = new PVector();
  10.   camRadius = 250.0f;
  11.   camTheta = 70.0f;
  12.   camPhi = -25.0f;
  13.   updateCamera();
  14. }
  15. void draw() {
  16.   background(255);
  17.   lights();
  18.   if (mousePressed) {
  19.     camTheta += (mouseX-pmouseX)*compensation;
  20.     camPhi += (mouseY-pmouseY)*compensation;
  21.     println(camPhi);
  22.   }
  23.   updateCamera();
  24.   camera(cam.x, cam.y, cam.z, 0, 0, 0, 0, 1, 0);
  25.  
  26.   sphereDetail(15);
  27.   fill(255);
  28.   stroke(255);
  29.   sphere(25);
  30. }
  31. public void updateCamera() {
  32.   cam.x = camRadius * sin(camTheta)*sin(camPhi);
  33.   cam.y = camRadius * -cos(camPhi);
  34.   cam.z = camRadius * -cos(camTheta)*sin(camPhi);
  35.   redraw();
  36. }
can anyone help me figure this out?

Replies(2)

Several points to make.

First sin(angle) and cos(angle) expect angle to be in radians NOT degrees. The initial values you set are obvious degrees.

When rotating in the east<>west direction the angle can be in the range 0-360 degrees (0 - TWO_PI radians) and the rangge for north<>south is 0-180 degrees (0 - PI radians). In your program the range of values for N<>S is 360 rather than 180 degrees.
 
Also you have disabled the depth test which reinforces the problem.

In the code below I have enabled the depth test, change the initial values for the angles to radians, changed the backgorund colour to make it easier to see what is happening and added a new function fixAnle to keep the angles within the permitted range.

I have also removed the redraw command from the updateCamera function since this method is called from the draw() method so is not needed. Also it is not a good idea to call redraw while draw() is being executed.

HTH

Copy code
  1. import processing.opengl.*;
  2. PVector cam;
  3. float camRadius, camTheta, camPhi;
  4. private final static float compensation = 0.05f;

  5. void setup() {
  6.   size(500, 500, OPENGL);
  7.   hint(ENABLE_OPENGL_4X_SMOOTH);
  8.   hint(ENABLE_DEPTH_TEST);
  9.   cam = new PVector();
  10.   camRadius = 250.0f;
  11.   camTheta = 1.22f;
  12.   camPhi = 2.7f;
  13.   updateCamera();
  14. }

  15. void draw() {
  16.   background(64);
  17.   lights();
  18.   if (mousePressed) {
  19.     camTheta += (mouseX-pmouseX)*compensation;
  20.     camTheta = fixAngle(camTheta, TWO_PI);
  21.     camPhi += (mouseY-pmouseY)*compensation;
  22.     camPhi = fixAngle(camPhi, PI);
  23.     println(camPhi);
  24.   }
  25.   updateCamera();
  26.   camera(cam.x, cam.y, cam.z, 0, 0, 0, 0, 1, 0);
  27.   sphereDetail(15);
  28.   fill(255);
  29.   stroke(255);
  30.   sphere(25);
  31. }
  32. public float fixAngle(float ang, float range) {
  33.   if (ang < 0)
  34.     ang += range;
  35.   else if (ang > range)
  36.     ang -= range;
  37.   return ang;
  38. }
  39. public void updateCamera() {
  40.   cam.x = camRadius * sin(camTheta)*sin(camPhi);
  41.   cam.y = camRadius * -cos(camPhi);
  42.   cam.z = camRadius * -cos(camTheta)*sin(camPhi);
  43. }


thank you so much i've been banging my head against the wall for like 3-4 days trying figure this out, you have been a great help. Thanks again