How to rotate around a sphere?

I spawn a sphere not at the center of the space, and I would like the “camera” to rotate around that sphere, always looking towards the sphere’s center. According to https://gist.github.com/atduskgreg/1516424, it should be very easy, namely translate to the sphere’s center and then apply a rotation. However in my case it doesn’t work.
Here is a reasonable MWE (if you provide a solution I hope I can adapt it to my code afterwards):

int box_x = 550;
int box_y = 550;

void settings() {
  System.setProperty("jogl.disable.openglcore", "true");
  size(box_x, box_y, P3D);
}

void setup() {
  frameRate(500);
  background(0);
  noFill();
  translate(box_x/2.0, box_y/2.0, 0);
}

void draw() {
  background(0);

    translate(width/2-328, height/2-43, 500);
    rotateY(frameCount / 100.0);

  fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  translate(328, 43, 0);
  sphereDetail(55);
  sphere(100);
}

The problem, I think, is that despite the fact that the sphere is spawn where I want it to be, the axis of rotation does not match the sphere’s one. How can I fix this?

Look at the camera () command

In short center is your sphere

Cam pos can be calculated with cos and sin mult radius plus sphere position

(See tutorials | trigonometry primer)

Hello,

translate in setup() will not apply to draw():
https://processing.org/reference/translate_.html < There is a statement here about it resetting at start of draw()

I tinkered with your code a bit and the sphere is rotating around center.
This may give you something to think about.

int box_x = 550;
int box_y = 550;

void settings() {
  System.setProperty("jogl.disable.openglcore", "true");
  size(box_x, box_y, P3D);
}

void setup() {
  frameRate(500);
  background(0);
  noFill();
  //translate(box_x/2.0, box_y/2.0, 0);
}

void draw() {
  background(0);

  translate(box_x/2.0, box_y/2.0, 0);

  //translate(width/2-328, height/2-43, 500);
  rotateY(frameCount / 100.0);

  fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  translate(328, 43, 0);
  sphereDetail(55);
  sphere(100);
}

:)

Hmm the hint that I get is that I should use a single translate() call in the draw() function. So I would translate to the center of the sphere, then rotateY(). I should not translate once more, I guess. But I am going nowhere either way.

Hello,

Do some exploration of this.

Comment lines to see what happens.
Rearrange the order of translate() and rotateY() to see what happens.

This may help:

I like to add text to see where transformed co-ordinates are:

textSize(24);
fill(255, 0, 0);
text("0, 0, 0", 0, 0);

:)

1 Like

Thanks for the tips, I will use them in future. I am a little bit puzzled, after “playing” with commenting rotate and translate and reordering them.
For example this code:

void draw() {
  background(0);
  //translate(width/2-328, height/2-43, 200);
  //rotateY(frameCount / 100.0);
  //translate(box_x/2.0-328, box_y/2.0-43, 200);
  //rotateY(frameCount / 100.0);

  fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  translate(328, 43, 0);
  sphereDetail(15);
  sphere(100);
  textSize(24);
fill(255, 0, 0);
text("0, 0, 0", 0, 0);
text("328, 43, 0", 328, 43,0);

I would expect to be translated to the sphere’s center, namely the point (328, 43, 0). But no, instead that point looks up and on the left, I conclude that I must close to (0,0,0) even though I do not see the indicator (strange?). So I add “translate(328, 43, 0);” at the beginning or at the end of draw(), but I am still not transported anywhere close to the sphere.

Should I use pushMatrix() and popMatrix()?

Ok, I am now completely lost despite having read the documentation for translate and the pages you linked.
In this code, I do not see any difference visually if I change the values of the last translate(); function:

void draw() {
  background(0);

  fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  pushMatrix();
  translate(328, 43, 0);
  sphereDetail(15);
  sphere(100);
  popMatrix();
  
  textSize(24);
fill(255, 0, 0);
text("0, 0, 0", 0, 0);
text("328, 43, 0", 328, 43,0);
  translate(-328, -43, 0);
}

What’s more, the sphere in that example, seems to be built around (0,0,0), as it should, but since I do not do any translate(); statement, I would expect to be spawned at the origin too, at the beginning of the draw(); function, but apparently this isn’t the case. Hmm…

Edit: Ok, I don’t see any change because I do not do anything after that last translate command. Good.
Edit 2 : Going nowhere. I remove pushMatrix(); and the associated translate();, the sphere looks static while the coordinate system rotates, ok great, it means the camera is also static with respect to the sphere and that it’s the coordinate system that rotates according to my reference frame… but then what? How am I supposed to achieve my goal to rotate around the sphere? I just don’t see it, yet.

The size of your canvas is 550 x 550.

Where are the co-ordinates (328, 43, 0) coming from?

:)

They are just “random” coordinates I picked. I tried to make sure the sphere would be in. Is there any problem with the coordinates? I really do not see anything wrong with them!

Edit: Nevermind. I shouldn’t pick anything bigger than 550/2.0 I think.

Edit2: Nevermind again, I just increased the canvas to 850 x 850 and I see exactly the same things.

I am still entirely lost. I do not understand why, in the following example, the rotation seems to be around the y axis when x=0 (i.e. around the y axis that passes through (0,0,0)) rather than around the point (328, 43, 0).

void draw() {
  background(0);
  translate(328, 43, 0);
  rotateY(frameCount / 100.0);
  fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  pushMatrix();
  translate(328, 43, 0);
  sphereDetail(15);
  sphere(100);
  popMatrix();
  
  
  textSize(24);
fill(255, 0, 0);
text("0, 0, 0", 0, 0);
text("328, 43, 0", 328, 43,0);
}

I’ve got a little bit more familiar with the order of things. For example I know how to make the sphere rotate by using rotateY() just before the sphereDetail() line.

Using logic, I would expect that, in the above example, I should rotate around the sphere. Not the sphere around the y axis that passes through (0,0,0). What is wrong with my thoughts?

I am thinking that maybe it isn’t possible with any of rotateX, rotateY and rotateZ. Maybe it has to be with rotate();, but it is still not clear to me. Those X, Y and Z versions all rotate with respect to the axis. So, if the sphere is not centered along any axis, as is the case in my example, then I think there’s no way to achieve what I want with any of those 3 functions.
But that’s just another random shot towards getting my problem solved. Any help is immensely appreciated.

You don’t like my solution?

1 Like

I am realizing your solution might be the only one! I am about to try it!

1 Like

I mentioned to use camera(), but here is an Explanation without using the camera() command.

Explanation without camera

Here you rotate the entire scene and camera is fixed

You can see the difference between rotation scene and rotation camera when you use the lights(); command.

Rotation is always around the center 0,0 of the Matrix. In 3D you can obviously rotate around
Different axis x,y or z.

Before rotate we say translate() to place the rotation center at this point (which is then 0,0)

Try

translate...
rotateY
translate (300,0,0);
sphere

to achieve a rotation with radius 300


for example rotation around itself




float angle=0;

void setup() {
  size( 1600, 600, P3D );
}

void draw() {
  background(0); 
  lights();

  translate (500, 400, -111); 
  rotateY(angle);

  fill(0, 255, 0); //green
  box(21);

  angle+= 0.01411;
}

for example rotation on a circle around a center




float angle=0;

void setup() {
  size( 1600, 600, P3D );
}

void draw() {
  background(0); 
  lights();

  translate (500, 400, -111); 
  rotateY(angle);

  translate (200, 0, 0); 

  fill(0, 255, 0); //green
  box(21);

  angle+= 0.01411;
}

for example with 2 boxes




float angle=0;

void setup() {
  size( 1600, 600, P3D );
}

void draw() {
  background(0); 
  lights();

  translate (500, 400, -111); 
  rotateY(angle);

  fill(0, 255, 0); //green
  box(21);

  translate (300, 0, 0);

  fill(255, 0, 0); //red
  box(21);

  angle+= 0.01411;
}

See also https://processing.org/tutorials/p3d/

The thing is, I do not want a rotation with any radius, i.e. I do not want the sphere to “orbit”, I want it to spin on itself, just in front of the camera. (Uh, I mean the camera “orbits” the sphere that is static with respect to the background… this is confusing!)

With your camera suggestion I think I know how to do it (judging from reading the documentation only), I will try.

1 Like

Ok, here is my try:

  float cam_x = 250 * cos(PI/100*frameCount);
  float cam_y = 250 * sin(PI/100*frameCount);
  camera(cam_x, cam_y, 250, 328, 43, 0, 0, 1, 0);

In my mind, this is supposed to place the camera on a circle of radius 250 looking toward the center of the sphere, and that the position of the camera itself should move along that circle as the number of frame goes up. However this is not what happens. I see a strange oscillatory motion towards the sphere, which also seems to rotate with respect to the z axis. Very very strange! I do not understand what is going on.

Ok, I have read more, but I am still unable to get it right. I do not understand why the following doesn’t work:

void draw() {
  background(0);
  float cam_x = 250 * cos(radians(2*PI/10*frameCount));
  float cam_z = 250 * sin(radians(2*PI/10*frameCount));
  camera(cam_x, 43, cam_z, 328, 43, 0, 0, 1, 0);

    fill(128, 0, 128);
  stroke(128, 0, 128);
  lights();
  translate(328, 43, 0);
  sphereDetail(35);
  sphere(100);
  textSize(24);
  fill(255, 0, 0);
  text("0, 0, 00000000000000000000000", 0, 0);
  text("328, 43, 0 test", 328, 43, 0);
}

Running the code indicates that the camera is always looking at the center of the sphere, which is what I seek. However the distance between the camera and the sphere oscillates, while I want it constant. As I understand it, I want to orbit the camera in the x-z plane at the constant y=43 value (matching the center of the sphere). This is what I think my code should do, but apparently doesn’t. Running the code shows that the camera goes even inside the sphere and reaches the (0,0,0) indicator. But cam_x and cam_z cannot be possibly zero at once… What is going on?!

The angle is in radians

0…2 Pi

Use map() to get this angle.

frameCount doesn‘t do the job

You can say : radians(angle)

angle += 1; // in degree

Hmm, I do not understand. It shouldn’t matter if I use radians() or not, this only modifies the “speed” of rotation, not the path described by the camera.

Why wouldn’t frameCount do the job? I have something equivalent to x=Acos(omega t) and z=Asin(omega t).

Am I again missing something?

1 Like