让行星的速度与其距离的平方反比成比例?

发布于 2025-01-12 12:26:55 字数 858 浏览 0 评论 0原文

按照这个优秀教程制作一个程序化的太阳系,到目前为止进展顺利。我唯一的问题是轨道速度没有我想要的那么准确。我希望轨道周期遵循开普勒第三定律。唯一的问题是我不知道如何让它像那样工作。

这是与轨道相关的代码。我怎样才能让它按照我想要的方式工作?

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;
      "
    />
  `;
}

Following this excellent tutorial on making a procedural solar system, and so far it's coming along nicely. My only problem with it is that the orbit speeds aren't as accurate as I'd like. I want the orbital periods to follow Kepler's Third Law. Only problem is that I don't know how to get it to work like that.

Here is the code related to the orbits. How do I get it to work how I want it to?

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;
      "
    />
  `;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↙厌世 2025-01-19 12:26:55

教程的作者在这里。我很高兴你喜欢它!

这是一个好问题。我不是天文学或数学专家,但我会尽力回答。

通过自定义属性设置速度

首先要知道的是,旋转速度是由 --rotation-speed 自定义属性控制的。我们将该值从 distance * randomInt(40, 70) 更新为更准确的值。现在这是以毫秒为单位设置的。

因此,我们需要确定将该自定义属性设置为什么值。

非科学警告

我将在数学中采取一些捷径:

  • 开普勒定律有复杂的数学来解释大多数轨道是椭圆形(不是圆形)的事实。我的教程使用圆形轨道,这使得匹配更简单。 (对于额外的挑战,您可以尝试切换到椭圆轨道)
  • 显然,现实生活中的轨道太慢,我们无法观察到,因此我们需要加快它们的速度,但使它们彼此之间的关系更加真实。

确定更准确的速度

考虑到这些注意事项,让我们找到一个可以使用的公式。我发现这篇有用的文章描述了如何计算圆形轨道速度: 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;
      "
    />
  `;
}

这里是 一个 codepen 显示它的实际操作。正如我上面提到的,我不是天文学家,但我认为这应该为您指明正确的方向。快乐编码!

Author of the tutorial here. I'm glad you enjoyed it!

This is a good question. I'm not an expert on astronomy or mathematics, but I'll do my best to answer.

Setting Speed Via Custom Property

The first thing to know is that the rotation speed is controlled by the --rotation-speed custom property. We'll be updating that value from distance * randomInt(40, 70) to a more accurate value. Right now this is set in milliseconds.

So we need to determine what value to set that custom property to.

Non-scientific caveats

I'm going to be taking a couple short-cuts in my math here:

  • Kepler's law has complex math to account for the fact that most orbits are elliptical (not circular). My tutorial is using circular orbits, which makes the match simpler. (For an additional challenge you could try switching to elliptical orbits)
  • Obviously real-life orbits are too slow for us to observe, so we'll need to speed them up, but make them more realistic in relation to eachother.

Determining a more accurate speed

With those caveats in mind, let's find a formula we can use. I found this helpful article which describes how to calculate circular orbital speeds: https://www.nagwa.com/en/explainers/142168516704/

Here's a JS approximation of the formula they outline in the article:

function velocity(gravitationalConstant, starMass, orbitDistance) {
  return Math.sqrt((gravitationalConstant * starMass) / orbitDistance);
}

This just gets us the velocity though. To set the animation speed we need to know how long the entire orbit will take. We could figure this out by determining the circumference of the orbit, and comparing that to the velocity. Here's how we can get the orbit circumference:

function circumference(radius) {
  const diameter = radius * 2;
  return Math.PI * diameter;
}

We can do something similar in the drawPlanet function:

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;
      "
    />
  `;
}

Here's a codepen showing it in action. As I mentioned above, I'm no astronomer, but I think this should point you in the right direction. Happy coding!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文