我正在尝试建立太阳能系统的比例模型。我想看看是否有人可以向我解释旋转速度的工作原理。这是重要的一部分:
objects[index].rotation.y += calculateRotationSpeed(value.radius,value.revolution) * delta;
转速如何与实际时间相关?因此,如果您的速度为1,那么每毫秒的运动速度是1 px吗?或者,如果你的速度为0.1,那么它是一个px一秒吗?
基本上我正在尝试计算行星的正确旋转速度,考虑到它们的半径和一天中的小时数。因此,如果你在地球上,它将在24小时内完成1次旋转。这是我写的现在正在进行计算的函数:
/* 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;
}
我试一试,它似乎仍然移动得太快了。我还需要类似于计算轨道速度的东西。
答案 0 :(得分:63)
Three.JS中的旋转以弧度测量。对于那些完全不熟悉弧度的人(我的一篇旧论文的摘录):
与数学常数Pi一样,radian(大约57.3度)来自圆的半径(或直径)与其周长之间的关系。一个弧度是 角度,它始终跨越圆周上的圆弧,其长度等于同一圆的半径(对于任何圆都是如此,无论大小如何)。类似地,Pi是圆周与直径的比率,使得单位圆的周长恰好是Pi。弧度和度数实际上不是 true 单位,实际上角度通常是无量纲的(如百分比和分数,我们不使用实际单位来描述它们)。
然而,与度数不同,弧度是不任意定义,在大多数情况下使其成为更自然的选择;通常比在数学公式中使用度数更容易,更优雅,更清晰,更简洁。巴比伦人可能给了我们度数,将他们的圆圈分成6个相等的部分(使用等边三角形的角度)。给定sexagesimal(基数60)数字系统,这6个部分中的每一部分可能进一步细分为60个相等的部分。这也允许他们使用这样的系统进行天文学,因为一年中估计的天数在他们的时间内准确性要低得多,通常被认为是360天。
现在,如果您使用anim
函数中一次的第一次增量,那么现在知道您正在使用弧度工作(回调requestAnimFrame
),您将在x轴上将mesh
的旋转增加一个弧度
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
轻松地将度数值转换为弧度,如果我们希望使用度数。
在您的情况下,您需要考虑每帧经过多少时间。这是您的 delta 。你必须这样想:我们运行多少FPS?我们将声明一个全局clock
变量,它将存储一个THREE.Clock
对象,该对象具有我们所需信息的接口。我们需要一个全局变量,我们将调用clock
(需要在其他函数中访问,特别是anim
):
在init
内,创建THREE.Clock
的实例;将它存储在init
之外声明的变量中(范围更大):
clock = new THREE.Clock();
然后,在您的anim
函数中,您将进行两次调用,以更新与clock
相关联的两个变量:
time
(自实例化时钟以来经过的总时间(以毫秒为单位))delta
(每帧之间的时间,以毫秒为单位)在另外两个全局变量中:time = clock.getElapsedTime(); delta = clock.getDelta();
请注意delta
意味着返回每帧之间的时间量;但是,如果在<{1}} / clock.getDelta
anim
被render
,那么这将是真实的
以上条件是THREE.Clock
实施的结果。 getDelta
最初返回自实例化时钟以来的时间量,之后返回的时间就是自上次调用时起的时间。如果它以某种方式被错误地或不一致地称为它会搞砸了。
现在,如果你的场景没有让处理器或GPU陷入困境,那么包含{。{3}}的Three.JS将尝试(使用可用资源)来保持平稳运行每秒60帧。这意味着理想情况下,每帧之间大约1/60 = .016666
秒,这是您delta
的值,您可以从clock
每帧读取该值,并根据帧速率使用它来标准化您的速度乘以如下所示。这样,您可以获得以秒为单位的值,而不管帧速率的微小变化,您可以每次乘以以获得以秒为单位的值。
因此,基于我们在anim
函数中的开头,您可以像这样使用它:
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
因为我们对角度,弧度和度数的测量实际上不是单位,所以当我们查看单位的角速度时,我们会发现它只能 时间(而不是你的代码中的距离和时间函数。)
至于您的具体情况,您不需要半径来计算转速(角速度),而是可以使用一天中的小时数(完整旋转所需的时间) ,即。2 * Math.PI
弧度在它的轴上旋转。如果您有一个名为revolutionTime
的变量,那么您可以像这样计算它。
secondsInAnHour = 3600;
rotationalSpeed = (2 * Math.PI) / revolutionTime;
如果你认为地球在一天内有24 hours = 24 * 60 * 60 = 86,400
(它没有)。然后,我们将获得rotationalSpeed = 2 * PI / 86,400
或大约0.0000727
每秒弧度。您应该能够找到比这更准确的教科书值(考虑到比我们的24小时平坦数字更精确的测量值,以确定地球完成一次革命所需的时间。
但是,我不担心确保行星的所有角速度完全正确。相反,一个更好的想法是弄清楚(行星的)每个角速度之间的比率是什么,并使用它。由于以下几个原因,这样可以更好地工作:您可能希望更快的转速,这将允许您使用任何转速效果良好;重要的是,与任何模型一样(特别是当涉及到天文模型时),就是你要保持它的规模。