corvid
corvid

Reputation: 11177

rotating relative to another object

I am making a basic Three.js application One of my goals is to move the moon in alignment with the Earth. While I do have a method which will statically make it rotate in a circle, if you move around the planet the moon's rotation will start to execute oddly -- going in elliptical shapes until catching back up in a few revolutions.

the logic for it can be found in the following function:

rotateMoon = function(rotSpeed) {
  var x = moon.position.x,
      y = moon.position.y,
      z = moon.position.z;
  moon.position.x = x * Math.cos(rotSpeed) + z * Math.sin(rotSpeed);
  moon.position.z = z * Math.cos(rotSpeed) - x * Math.sin(rotSpeed);
}

my goal is to "hook" it to the earth; which is to say, it's movement is dependent on the Earth's movement. How would this be achieved?

Upvotes: 1

Views: 1204

Answers (1)

Filipe
Filipe

Reputation: 1219

I suggest that you use THREE.js, this thing is very easy to do with it.

You can store an object like a child for another in this case Earth can be parent of Moon.

The code will be something like that below:

var earth = new THREE.Mesh(e_geometry, e_material);
var moon = new THREE.Mesh(m_geometry, m_material);
moon.position.x = 100;
earth.add(moon);

And in update method or function:

earth.rotation.y += 0.01;

At the THREE.js site you will found a big number of examples of this approach.

You might even take it a step further. This kind of setup is often called a scenegraph where each child is positioned, rotated, and scaled relative to it's parent. A scenegraph for a car might look like this

car
|
+--left front wheel
|
+--right front wheel
|
+--left rear wheel
|
+--right rear wheel

You'd do this by making the wheels children of the car. In three.js that would be

car.add(leftFrontWheel);
car.add(rightFrontWheel);
car.add(leftRearWheel);
car.add(rightRearWheel);

At that point moving the car also moves the wheels.

In the planet case though you want extra nodes so you rotate the moons around the earth and at the same time rotate the earth and the moon separately. If your scenegraph looked like this

earth
|
+--moon

The moon's orbit would be tied directly to the earth's rotation. If you do this though

earthBase (invisible)
|
+--earth
|
+--moonBase (invisible)
   |
   +--moon

Then you can rotate earth to make the earth rotate, you can rotate moonBase to make the moon orbit the earth, and you can rotate moon to make the moon rotate.

To make earthBase and moonBase use something like

var earthBase = new THREE.Object3D();
var moonBase = new THREE.Object3D();

Then setup the hierarchy

earthBase.add(earth);
earthBase.add(moonBase);
moonBase.add(moon);

Set the radius of the orbit of the moon with

moon.position.z = radiusOfMoonsOrbit;

Make the moon orbit with

moonBase.rotate.y += angularSpeedOfOrbit;

Make the earth and moon rotate with

earth.rotate.y += earthRotationalSpeed;
moon.rotate.y += moonRotationalSpeed;

Here's a fiddle http://jsfiddle.net/greggman/uY8Ce/

Upvotes: 5

Related Questions