旋转和单位
Three.JS 中的旋转以弧度为单位。对于那些完全不熟悉弧度的人(我的一篇旧论文的一小段摘录):
与数学常数Pi一样,弧度(大约 57.3 度)源自圆的半径(或直径)与其周长之间的关系。一个弧度是始终跨越一个圆的圆周上的弧的角度,该圆的长度等于同一个圆的半径(对于任何圆都是如此,无论大小)。类似地,Pi 是周长与直径的比值,因此单位圆的周长正好是 Pi。弧度和度数实际上不是真正的单位,实际上角度通常是无量纲的(如百分比和分数,我们不使用实际单位来描述它们)。
但是,与度数不同的是,弧度不是任意定义的,因此在大多数情况下,它是更自然的选择;通常比在数学公式中使用度数更容易、更优雅、更清晰、更简洁。巴比伦人可能给了我们度数,将他们的圆分成 6 个相等的部分(使用等边三角形的角度)。考虑到它们的六十进制(以 60 为底)的数字系统,这 6 个部分中的每一个都可能进一步细分为 60 个相等的部分。这也将允许他们将这样的系统用于天文学,因为在他们的时间里,一年中的估计天数要准确得多,通常被认为是 360 天。
Three.JS 中的基本旋转
所以现在,知道您正在使用弧度,如果您在函数中使用以下第一个语句增加一次anim
(回调到requestAnimFrame
),您将mesh
在 x 轴上的旋转增加一个弧度
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
正如上面的最后两个语句所示,Math.PI / 180
如果我们希望使用度数来代替,我们可以在赋值之前轻松地将度数转换为弧度。
考虑帧率
在您的情况下,您需要考虑每帧经过多少时间。这是你的delta。你必须这样想:我们以多少 FPS 运行?我们将声明一个全局clock
变量,该变量将存储一个THREE.Clock
对象,该对象具有我们所需信息的接口。我们需要一个我们将调用的全局变量clock
(需要在其他函数中可访问,特别是anim
):
在 内init
,创建一个实例THREE.Clock
;将其存储在外部声明的变量中init
(范围更大):
clock = new THREE.Clock();
然后,在您的anim
函数中,您将进行两次调用,以更新与以下相关的两个变量clock
:
time
(自时钟实例化以来经过的总时间(以毫秒为单位))
delta
(每帧之间的时间以毫秒为单位)在其他两个全局变量中:
时间 = 时钟.getElapsedTime();
delta = clock.getDelta();
请注意,这delta
意味着返回每帧之间的时间量;然而,当且仅当clock.getDelta
在anim
/render
- 每个动画/渲染周期只有一次
- 每个动画周期都在同一个地方(开始或结束,据我所知,哪个不重要)
上述条件是THREE.Clock
执行的结果。getDelta
最初返回自时钟实例化以来的时间量,之后它返回的时间只是自上次调用以来的时间)。如果它以某种方式被错误地或不一致地调用,它将把事情搞砸。
以增量因子旋转
现在,如果您的场景没有让处理器或 GPU 陷入困境,Three.JS 及其包含的requestAnimationFrame shim将尝试(使用可用资源)以保持每秒 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 小时平面数字更准确的测量值,即地球完成一圈所需的时间。
特别考虑你的情况
但是,我不会担心确保行星的所有角速度都完全正确。相反,一个更好的主意是计算出(行星的)每个角速度之间的比率并使用它。这将更好地工作有几个原因:您可能想要更快的旋转速度,这将允许您使用任何有效的旋转速度;重要的是,与任何模型一样(尤其是在涉及天文模型时),你要保持它的规模。