Three.JS的单位,计算旋转和轨道速度 [英] Units of Three.JS, Calculating Rotation & Orbit Speeds

查看:345
本文介绍了Three.JS的单位,计算旋转和轨道速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立太阳系的比例模型.我想看看是否有人可以向我解释转速的工作原理.这是重要的部分:

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;

转速与实际时间有何关系?因此,如果您的速度为1,那是每毫秒1 px的运动吗?或者,如果您的速度为0.1,每秒的像素数是否小于px?

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?

基本上,我正在尝试根据行星的半径和一天中的小时数来计算它们的正确旋转速度.因此,如果您在地球上,它将在24小时内完成1次旋转.这是我编写的现在正在执行计算的函数:

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.

推荐答案

旋转和单位

Three.JS中的旋转度以弧度为单位.对于那些完全不熟悉弧度的人(摘自我的旧论文的一小部分):

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):

像数学常数 Pi 一样,是 弧度 (大约57.3度)是从圆的半径(或直径)之间的关系得出的)及其周长.一个弧度是 the 角,它将始终在圆的圆周上跨越一条弧,该圆的长度等于该同一个圆的半径(对于任何圆,无论大小,均适用).类似地,Pi是周长与直径的比率,因此单位圆的周长正好是Pi.弧度和度实际上不是 true 单位,实际上,角度通常是无量纲的(如百分比和分数,我们不使用实际单位来描述它们).

Like the mathematical constant Pi, a radian (roughly 57.3 degrees) is derived from the relationship between a circle's radius (or diameter) and its circumference. One radian is the angle which will always span an arc on the circumference of a circle which is equal in length to the radius of that same circle (true for any circle, regardless of size). Similarly, Pi is the ratio of circumference over diameter, such that the circumference of the unit circle is precisely Pi. Radians and degrees are not actually true units, in fact angles are in general dimensionless (like percentages and fractions, we do not use actual units to describe them).

但是,与度数不同的是,弧度不是任意定义的,因此在大多数情况下,弧度是更自然的选择.通常比在数学公式中使用度数更容易,而且更优雅,清晰和简洁.巴比伦人可能给了我们度数,将他们的圆分成6个相等的部分(使用等边三角形的角度).给定它们的 性爱 ,这6个部分中的每一个都可能进一步细分为60个相等的部分a>(以60为基数)数字系统.这也将使他们能够将这种系统用于天文学,因为一年中估计的天数在他们的时间内不那么准确,通常被认为是360天.

However, unlike the degree, the radian was not defined arbitrarily, making it the more natural choice in most cases; often times being much easier and much more elegant, clear, and concise than using degrees in mathematical formulae. The Babylonians probably gave us the degree, dividing their circle into 6 equal sections (using the angle of an equilateral triangle). each of these 6 sections were probably further subdivided into 60 equal parts given their sexagesimal (base 60) number system. This would also allow them to use such a system for astronomy because the estimated number of days in a year was much less accurate during their time and was often considered 360.

Three.JS中的基本旋转

现在,如果您知道工作的是弧度,则可以在anim函数中使用以下语句一次 first 进行递增(回调到),您将使mesh在x轴上的旋转增加一个弧度

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 to requestAnimFrame), you will be incrementing the rotation of mesh on the x-axis by one radian

mesh.rotation.x += 1;                      // Rotates   1 radian  per frame
mesh.rotation.x += Math.PI / 180;          // Rotates   1 degree  per frame
mesh.rotation.x += 45 * Math.PI / 180      // Rotates  45 degrees per frame

如上面的 last 所示,如果希望使用度数,可以使用Math.PI / 180轻松地将赋值前的度值转换为弧度.

As 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.

在您的情况下,您需要考虑每帧花费多少时间.这是您的 delta .您必须这样思考:我们运行多少FPS?我们将声明一个全局clock变量,该变量将存储一个THREE.Clock对象,该对象具有所需信息的接口.我们需要一个称为clock的全局变量(需要在其他函数中访问,特别是anim):

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 a THREE.Clock object which has an interface to the information we require. We need a global variable we'll call clock (needs to be accessible in other functions, specifically anim):

init内,创建THREE.Clock的实例;将其存储在init外部声明的变量中(范围更大):

Within init, create an instance of THREE.Clock; storing it in the variable declared outside init (with a greater scope):

clock = new THREE.Clock();

然后,在您的anim函数中,您将进行两次调用,这将更新与clock相关联的两个变量:

Then, in your anim function, you'll make two calls that will update two variables associated with clock:

  • time(自实例化时钟以来经过的总时间(以毫秒为单位))
  • delta(每帧之间的时间,以毫秒为单位),位于其他两个全局变量中:
  • time (total elapsed time in milliseconds since the clock was instantiated)
  • delta (time in milliseconds between each frame) in two other global variables:

 time = clock.getElapsedTime();
 delta = clock.getDelta();

请注意,delta meant ,用于返回每帧之间的时间;但是,如果在anim/render

Note that delta is meant to return the amount of time between each frame; however, this will be true if and only if clock.getDelta is consistently called within anim/render

  1. 每个动画/渲染周期一次
  2. 每个动画周期都在同一位置(开始或结束,据我所知这并不重要)
  1. Only once each animation/render cycle
  2. In the same place each animation cycle (beginning or end, which one shouldn't matter as far as I know)

以上条件是THREE.Clock实现的结果. getDelta最初返回自实例化时钟以来的时间,此后返回的时间就是自上次调用以来的时间.如果它以某种方式被错误或不一致地调用,将会使事情搞砸.

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.

现在,如果您的场景没有陷入处理器或GPU的深渊,那就使用Three.JS及其它 requestAnimationFrame填充程序 将尝试(使用可用资源)使事物以每秒60帧的速度平稳运行.这意味着理想情况下,每帧之间的间隔大约为1/60 = .016666秒,这是您可以从clock每一帧中读取的delta值,并使用它根据帧频通过乘以如下所示来标准化速度.这样,您就可以以秒为单位获取一个值,而不必考虑帧率的微小变化,您可以每次相乘以获取以秒为单位的值.

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 your delta value which you can read from the clock 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.

因此,根据我们在anim函数开始时所拥有的内容,可以像这样使用它:

So, based on what we had at the beginning in your anim function you can use it like so:

mesh.rotation.x += delta * 1;                     // Rotates  1 radian  per second
mesh.rotation.x += delta * Math.PI / 180;         // Rotates  1 degree  per second
mesh.rotation.x += delta * 45 * Math.PI / 180;    // Rotates 45 degrees per second

转速和单位

因为我们测量的角度,弧度和度数实际上不是单位,所以当我们查看角速度的单位时,我们会发现它仅作用于 时间(而不是作为距离和时间的函数,就像您在代码中一样).

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).

对于您的具体情况,您不需要用半径来计算转速(角速度),而是可以使用一天中的小时数(完整旋转所花费的时间,即.2 * Math.PI 弧度在其轴上的旋转).如果您有一个名为revolutionTime的变量,则可以这样计算.

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 called revolutionTime then you can calculate it like so.

secondsInAnHour = 3600;
rotationalSpeed = (2 * Math.PI) / revolutionTime;

如果您假设地球一天内有24 hours = 24 * 60 * 60 = 86,400(没有).然后我们将得到rotationalSpeed = 2 * PI / 86,400或大约0.0000727 弧度每秒.您应该能够找到比这更准确的教科书值(考虑到地球完成一次革命所花费的时间比我们的24小时平面图更准确的测量结果.

If you assume Earth has 24 hours = 24 * 60 * 60 = 86,400 in a day (it doesn't). Then we will get rotationalSpeed = 2 * PI / 86,400, or roughly 0.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.

但是,我不必担心要确保您对行星的所有角速度都完全正确.取而代之的是,一个更好的主意是找出(行星的)每个角速度之间的比率,并使用该比率.由于以下几个原因,它会更好地工作:您可能需要更快的旋转速度,这将允许您使用任何运转良好的旋转速度;与任何模型(尤其是天文模型)一样,重要的是要保持其缩放比例.

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.

这篇关于Three.JS的单位,计算旋转和轨道速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆