让行星的速度与其距离的平方成反比?
Getting a planet's speed to scale with the inverse square of it's distance?
按照 excellent tutorial 制作程序太阳系,到目前为止进展顺利。我唯一的问题是轨道速度没有我想要的那么准确。我希望轨道周期遵循开普勒第三定律。唯一的问题是我不知道如何让它像那样工作。
这是与轨道相关的代码。我如何让它按照我想要的方式工作?
function drawPlanet(size, distance) {
const hue = randomInt(0, 360);
const saturation = randomInt(70, 100);
const lightness = randomInt(50, 70);
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
return `
<circle
cx="${width / 2 + distance}"
cy="${height / 2}"
r="${size}"
fill="${color}"
class="planet"
style="
--start-rotation:${randomInt(0, 0)}deg;
--rotation-speed:${distance * randomInt(40, 70)}ms;
"
/>
`;
}
这里是教程的作者。很高兴你喜欢它!
这是个好问题。我不是天文学和数学方面的专家,但我会尽力回答。
通过自定义设置速度 属性
首先要知道的是旋转速度是由--rotation-speed
自定义属性控制的。我们将该值从 distance * randomInt(40, 70)
更新为更准确的值。现在这是以毫秒为单位设置的。
因此我们需要确定将自定义 属性 设置为什么值。
Non-scientific 注意事项
我要在这里学习一些 short-cuts 的数学:
- 开普勒定律用复杂的数学来解释大多数轨道是椭圆形(而非圆形)的事实。我的教程使用的是圆形轨道,这使得匹配更简单。 (对于额外的挑战,您可以尝试切换到椭圆轨道)
- 显然 real-life 轨道太慢了我们无法观察,所以我们需要加快它们的速度,但要使它们彼此之间的关系更加真实。
正在确定更准确的速度
考虑到这些注意事项,让我们找到一个可以使用的公式。我发现这篇有用的文章描述了如何计算圆形轨道速度:https://www.nagwa.com/en/explainers/142168516704/
这是他们在文章中概述的公式的 JS 近似值:
function velocity(gravitationalConstant, starMass, orbitDistance) {
return Math.sqrt((gravitationalConstant * starMass) / orbitDistance);
}
这只是让我们获得了速度。要设置动画速度,我们需要知道整个轨道需要多长时间。我们可以通过确定轨道的周长并将其与速度进行比较来解决这个问题。以下是我们如何获得轨道周长:
function circumference(radius) {
const diameter = radius * 2;
return Math.PI * diameter;
}
我们可以在 drawPlanet
函数中做类似的事情:
function drawPlanet(size, distance) {
const hue = randomInt(0, 360);
const saturation = randomInt(70, 100);
const lightness = randomInt(50, 70);
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
// Since we're only worried about _relative_ orbit speeds we can set
// this to whatever we like
const gravitationalConstant = 1;
// We could pass the size of the star into our function and use
// that to generate a star mass if we'd like.
// Then the orbit speeds would differ based on the star size.
// For now, let's hard code it.
const starMass = 1;
// We already know the orbit distance, so we have the radius.
const orbitRadius = distance;
// Apply our formulas
const velocity = Math.sqrt((gravitationalConstant * starMass) / orbitRadius);
const orbitCircumference = Math.PI * orbitRadius * 2;
// Compare the velocity to the orbit circumference to find the duration
// of a single orbit
const orbitDuration = orbitCircumference / velocity;
return `
<circle
cx="${width / 2 + distance}"
cy="${height / 2}"
r="${size}"
fill="${color}"
class="planet"
style="
--start-rotation:${randomInt(0, 0)}deg;
--rotation-speed:${orbitDuration}ms;
"
/>
`;
}
这里 a codepen 展示了它的实际效果。正如我上面提到的,我不是天文学家,但我认为这应该为您指明正确的方向。编码愉快!
按照 excellent tutorial 制作程序太阳系,到目前为止进展顺利。我唯一的问题是轨道速度没有我想要的那么准确。我希望轨道周期遵循开普勒第三定律。唯一的问题是我不知道如何让它像那样工作。
这是与轨道相关的代码。我如何让它按照我想要的方式工作?
function drawPlanet(size, distance) {
const hue = randomInt(0, 360);
const saturation = randomInt(70, 100);
const lightness = randomInt(50, 70);
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
return `
<circle
cx="${width / 2 + distance}"
cy="${height / 2}"
r="${size}"
fill="${color}"
class="planet"
style="
--start-rotation:${randomInt(0, 0)}deg;
--rotation-speed:${distance * randomInt(40, 70)}ms;
"
/>
`;
}
这里是教程的作者。很高兴你喜欢它!
这是个好问题。我不是天文学和数学方面的专家,但我会尽力回答。
通过自定义设置速度 属性
首先要知道的是旋转速度是由--rotation-speed
自定义属性控制的。我们将该值从 distance * randomInt(40, 70)
更新为更准确的值。现在这是以毫秒为单位设置的。
因此我们需要确定将自定义 属性 设置为什么值。
Non-scientific 注意事项
我要在这里学习一些 short-cuts 的数学:
- 开普勒定律用复杂的数学来解释大多数轨道是椭圆形(而非圆形)的事实。我的教程使用的是圆形轨道,这使得匹配更简单。 (对于额外的挑战,您可以尝试切换到椭圆轨道)
- 显然 real-life 轨道太慢了我们无法观察,所以我们需要加快它们的速度,但要使它们彼此之间的关系更加真实。
正在确定更准确的速度
考虑到这些注意事项,让我们找到一个可以使用的公式。我发现这篇有用的文章描述了如何计算圆形轨道速度:https://www.nagwa.com/en/explainers/142168516704/
这是他们在文章中概述的公式的 JS 近似值:
function velocity(gravitationalConstant, starMass, orbitDistance) {
return Math.sqrt((gravitationalConstant * starMass) / orbitDistance);
}
这只是让我们获得了速度。要设置动画速度,我们需要知道整个轨道需要多长时间。我们可以通过确定轨道的周长并将其与速度进行比较来解决这个问题。以下是我们如何获得轨道周长:
function circumference(radius) {
const diameter = radius * 2;
return Math.PI * diameter;
}
我们可以在 drawPlanet
函数中做类似的事情:
function drawPlanet(size, distance) {
const hue = randomInt(0, 360);
const saturation = randomInt(70, 100);
const lightness = randomInt(50, 70);
const color = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
// Since we're only worried about _relative_ orbit speeds we can set
// this to whatever we like
const gravitationalConstant = 1;
// We could pass the size of the star into our function and use
// that to generate a star mass if we'd like.
// Then the orbit speeds would differ based on the star size.
// For now, let's hard code it.
const starMass = 1;
// We already know the orbit distance, so we have the radius.
const orbitRadius = distance;
// Apply our formulas
const velocity = Math.sqrt((gravitationalConstant * starMass) / orbitRadius);
const orbitCircumference = Math.PI * orbitRadius * 2;
// Compare the velocity to the orbit circumference to find the duration
// of a single orbit
const orbitDuration = orbitCircumference / velocity;
return `
<circle
cx="${width / 2 + distance}"
cy="${height / 2}"
r="${size}"
fill="${color}"
class="planet"
style="
--start-rotation:${randomInt(0, 0)}deg;
--rotation-speed:${orbitDuration}ms;
"
/>
`;
}
这里 a codepen 展示了它的实际效果。正如我上面提到的,我不是天文学家,但我认为这应该为您指明正确的方向。编码愉快!