Loading...
Logo
Processing Forum
Greetings,


I've been having some trouble converting from spherical to Cartesian coordinates. The program I am working on is a simulation of stars orbitting the center of a galaxy. Now, I'd like the center of the screen to represent the center of the galaxy and for the stars to orbit around that. However, I've had to do weird things to make my orbits look good and I think it's because I don't fully comprehend how 3D space is represented in Processing.

Normally, to get to Cartesian, I'd do something like:

Copy code
  1. x = cos(theta)*sin(phi)*r;
  2. y = sin(theta)*sin(phi)*r;
  3. z = cos(phi)*r;

But I want to make it relative to the center of the screen and since the axis are positioned different with positive x right, positive y down, and negative z into the screen, I'm confused exactly how to do it.


What sort of offset do I want? How do I make sure that it orbits something in the center of the screen? Are my equations correct?


Any thoughts would be great.

Replies(2)

" I've had to do weird things to make my orbits look good and I think it's because I don't fully comprehend how 3D space is represented in Processing."

You're probably doing weird things. Post your current code and we can poke holes in it for you.

The axis certainly start out as you've described them, but there's no reason they have to stay like that.
That's why we have translate, scale, and rotate operations.
For example, if you put the line:

// ...
void draw(){
  background(0);
  translate( width/2, height/2, 30);
// ...

into your sketch, you might be surprised about how much easier getting things to rotate about the center of the screen can be...
The following code is where I create a list of points along the orbit:

Copy code
  1. for (int i = 0; i < period; i += timeStep) {
  2.       theta = angularVelocity * i;
  3.       r = getRadius(theta);
  4.       // System.out.println("theta = " + theta);
  5.      
  6.       x = cos(theta)*sin(phi)*r;
  7.       y = sin(theta)*sin(phi)*r;
  8.       z = cos(phi)*r;
  9.      
  10.       // x = width/2.0 + r*cos(theta)*sin(phi);
  11.       //y = height/2.0 + r*sin(theta)*sin(phi);
  12.       //z = r*cos(phi) + 2 * a * e;
  13.      
  14.       path.add(new PVector((float)x,(float)y,(float)z));
  15.     }


My draw method looks something like this (taking your advice for translating to the center of the screen and /then/ drawing):

Copy code
  1. void draw(){
  2.   background(0);
  3.   lights();
  4.   noStroke();
  5.   translate(width/2, height/2, 30);
  6.   sphere(50);
  7.   for(Star s: planets){
  8.     s.draw();
  9.     s.incTimeStep();
  10.   }
  11.   for(PathTube curr: orbits){
  12.     curr.draw();
  13.   }
  14. }


To represent the orbits, I use this class that implements I_PathGen(from shapes3d). This is the relevant code which shows how it gets the x,y,z. 

class Orbit implements I_PathGen {
    public float x(float t) {
      // change this to return the calculated x
      // position along the path
      float theta = radians(t*360);
      float r = (float)getRadius(theta);
      float x = r*sin(theta)*cos(phi);
      return x;
    }
 
    public float y(float t) {
      // change this to return the calculated y
      // position along the path
      float theta = radians(t*360);
      float r = (float)getRadius(theta);
      float y = r*sin(theta)*sin(phi);
      return y;
    }
 
    public float z(float t) {
      // change this to return the calculated z
      //  position along the path
      float theta = radians(t*360);
      float r =(float) getRadius(theta);
      float z = r*cos(theta);
      return z;
    }
  }


(the code thingy wasn't working for the above code and I didn't feel like trying to fix it)


ANYWAY, when I run my program, the orbit draws correctly. At least, I think it does. The orbit /looks/ like it should. However, the sphere itself is kinda doing its own thing.


If you need any more code, let me know. Sorry about the weird names and everything.


Thanks.