I'm trying to build a to scale model of the solar system. I wanted to see if someone could explain to me how the rotation speed works. Here's the important piece:
objects[index].rotation.y += calculateRotationSpeed(value.radius,value.revolution) * delta;
How does the rotation speed relate to actual time? So if you have a speed of 1, is that a movement of 1 px per millisecond? Or if you have a speed of 0.1, is that less that a px a second?
Basically I'm trying to calculate the correct rotation speed for the planets given their radius and amount of hours in a day. So if you were on earth, it would complete 1 rotation in 24 hours. Here's the function that I wrote that's doing the calculation now:
/* In a day */
function calculateRotationSpeed(radius,hrs,delta) {
var cir = findCircumference(radius);
if(delta) {
var d = delta;
} else {
var d = 1;
}
var ms = hrs2ms(hrs) * d;
var pxPerMS = km2px(cir) / ms;
return pxPerMS;
}
I gave it a try and it still seems to be moving too fast. I also need something similar to calculate orbit speeds.
Rotation and Units
Rotation in Three.JS is measured in radians. For those that are completely unfamiliar with radians (a small excerpt from an old paper of mine):
Basic Rotation in Three.JS
So now, knowing you're working in radians, if you increment using the first of the following statements once in your
anim
function (callback torequestAnimFrame
), you will be incrementing the rotation ofmesh
on the x-axis by one radianAs the last two of the above statements show we can use
Math.PI / 180
to easily convert a value in degrees into radians before the assignment if we wish to use degrees instead.Taking Framerate Into Account
In your case, you need to take into consideration how much time passes with each frame. This is your delta. You have to think of it like this: How many FPS are we running at? We'll declare a global
clock
variable which will store aTHREE.Clock
object which has an interface to the information we require. We need a global variable we'll callclock
(needs to be accessible in other functions, specificallyanim
):Within
init
, create an instance ofTHREE.Clock
; storing it in the variable declared outsideinit
(with a greater scope):Then, in your
anim
function, you'll make two calls that will update two variables associated withclock
:time
(total elapsed time in milliseconds since the clock was instantiated)delta
(time in milliseconds between each frame) in two other global variables:Note that
delta
is meant to return the amount of time between each frame; however, this will be true if and only ifclock.getDelta
is consistently called withinanim
/render
The above conditions are a result of the
THREE.Clock
implementation.getDelta
initially returns the amount of time since the clock was instantiated, afterwards the time it returns is simply the time since it was last called). If it somehow gets called mistakenly or inconsistently it's going to screw things up.Rotating With A Delta Factor
Now if your scene doesn't bog down the processor or GPU, Three.JS and it's included requestAnimationFrame shim will try (working with the available resources) to keep things running at a smooth 60 frames per second. This means ideally we will have approximately
1/60 = .016666
seconds between each frame, this is yourdelta
value which you can read from theclock
each frame and use it to normalize your speed based on the framerate by multiplying as shown below. This way you can get a value in terms of seconds regardless of small variations in the framerate which you can multiply each time in order to get a value in terms of seconds.So, based on what we had at the beginning in your
anim
function you can use it like so:Rotational Speed and Units
Because our measures of angles, radians and degrees are not actually units then when we look at our units for angular velocity we will see that it is going to function of only time (rather than as a function of distance and time like you have in your code).
Calculating Rotational Speeds Based On Time
As for your specific case, you don't need the radius to calculate the rotational speed (angular velocity), instead you can use the number of hours in a day (the amount of time it takes for a complete revolution, ie.
2 * Math.PI
radians of rotation on it's axis). If you have a variable calledrevolutionTime
then you can calculate it like so.If you assume Earth has
24 hours = 24 * 60 * 60 = 86,400
in a day (it doesn't). Then we will getrotationalSpeed = 2 * PI / 86,400
, or roughly0.0000727
radians per second. You should be able to find textbook values which may be more accurate than this (taking into account a more accurate measurement than our 24 hour flat figure for the amount of time it takes for Earth to complete a revolution.Considering Your Case Particularly
However, I wouldn't worry about making sure you have all of the angular velocities for the planets exactly correct. Instead, a better idea would be to work out what the ratios between each of the angular velocities (of the planets) are and use that. This will work better for a few reasons: You will likely want a faster rotational speed, this will allow you to use whatever rotational speed works well; the important thing, as with any model (especially when it comes to astronomical models), is that you keep it to scale.